2012-10-16 11 views
6

Voglio scrivere un modello vettoriale matematico. Ho una classe che accetta tipo e dimensione come argomento del modello, con molti metodi operativi matematici. Ora voglio scrivere specializzazioni in cui Vector < 3> per esempio ha x, y, z come membri che si riferiscono rispettivamente ai dati [0..3].C++ - Usa modello predefinito come base per la specializzazione

Il problema è che non so come creare una specializzazione che eredita tutto dal modello predefinito senza creare una classe base o scrivere tutto due volte.

Qual è il modo più efficiente per farlo?

template<class Type, size_t Size> 
class Vector { 
    // stuff 
}; 

template<class T> 
class Vector<3,T>: public Vector { 
    public: 
     T &x, &y, &z; 
     Vector(): Vector<>(), x(data[0]), y(data[1]), z(data[2]){} 
     // and so on 
}; 
+2

Creazione di una classe base è l'approccio tipico lì. –

risposta

7

In qualche modo si dovrebbe essere in grado di trarre dalla implementazione di default, ma si è specializzata un'istanza, così come? dovrebbe essere una versione non specializzata che puoi essere in grado di derivarne. Ecco, questo è semplice:

// Add one extra argument to keep non-specialized version! 
template<class Type, size_t Size, bool Temp = true> 
class Vector { 
    // stuff 
}; 
// And now our specialized version derive from non-specialized version! 
template<class T> 
class Vector<T, 3, true>: public Vector<T, 3, false> { 
    public: 
     T &x, &y, &z; 
     Vector(): Vector<>(), x(data[0]), y(data[1]), z(data[2]){} 
     // and so on 
}; 
+0

Sebbene funzioni correttamente, mi sembra un po 'goffo (per me) avere un parametro di modello interno in un'interfaccia esterna. – Cameron

+0

L'utente non usa mai questo parametro di modello aggiuntivo, ovviamente si ha un'altra opzione che sia l'implementazione specializzata che quella predefinita derivano da una classe base che contiene un'implementazione reale! ma secondo me è un po 'più difficile di questa tecnica! – BigBoss

+0

@BigBoss Bello, grazie. – weltensturm

1

considerare la possibilità di questo in un po 'diverso, ma sarà raggiunto gli obiettivi, Aggiungere interfaccia esterna - intendo funzioni standalone X(), Y(), Z():

template<class T, size_t S> 
T& x(Vector<T, S>& obj, typename std::enable_if<(S>=1)>::type* = nullptr) 
{ 
    return obj.data[0]; 
} 

template<class T, size_t S> 
T& y(Vector<T, S>& obj, typename std::enable_if<(S>=2)>::type* = nullptr) 
{ 
    return obj.data[1]; 
} 

template<class T, size_t S> 
T& z(Vector<T, S>& obj, typename std::enable_if<(S>=3)>::type* = nullptr) 
{ 
    return obj.data[2]; 
} 

non c'è grande differenza tra:

Vector<T, 3>& obj 
return obj.x(); 

E

Vector<T, 3>& obj 
return x(obj); 

Come bonus: questa interfaccia funziona per le dimensioni corrispondenti.

Problemi correlati