Sto scrivendo una semplice libreria di matematica con un tipo di modello di vettore:specializzazioni modello di classe con funzionalità condivise
template<typename T, size_t N>
class Vector {
public:
Vector<T, N> &operator+=(Vector<T, N> const &other);
// ... more operators, functions ...
};
Ora voglio un po 'di ulteriore funzionalità specificamente per alcuni di questi. Diciamo che voglio le funzioni x()
e y()
su Vector<T, 2>
per accedere a determinate coordinate. Potrei creare una specializzazione parziale per questo:
template<typename T>
class Vector<T, 3> {
public:
Vector<T, 3> &operator+=(Vector<T, 3> const &other);
// ... and again all the operators and functions ...
T x() const;
T y() const;
};
Ma ora sto ripetendo tutto ciò che esisteva già nel modello generico.
Potrei anche utilizzare l'ereditarietà. Rinominare il modello generico per VectorBase
, avrei potuto fare questo:
template<typename T, size_t N>
class Vector : public VectorBase<T, N> {
};
template<typename T>
class Vector<T, 3> : public VectorBase<T, 3> {
public:
T x() const;
T y() const;
};
Tuttavia, ora il problema è che tutti gli operatori sono definiti in VectorBase
, in modo da tornare VectorBase
istanze. Questi non possono essere assegnati a Vector
variabili:
Vector<float, 3> v;
Vector<float, 3> w;
w = 5 * v; // error: no conversion from VectorBase<float, 3> to Vector<float, 3>
ho potuto dare Vector
un costruttore di conversione implicita per rendere questo possibile:
template<typename T, size_t N>
class Vector : public VectorBase<T, N> {
public:
Vector(VectorBase<T, N> const &other);
};
Tuttavia, ora sto convertendo Vector
-VectorBase
e viceversa. Anche se i tipi sono gli stessi in memoria, e il compilatore potrebbe ottimizzare tutto questo, è goffo e non mi piace avere un potenziale sovraccarico di runtime per quello che è essenzialmente un problema in fase di compilazione.
C'è qualche altro modo per risolvere questo?
Perché non solo eseguire 'x()' e 'y()' funzioni libere che prendono la specializzazione appropriata di 'Vector'? Per esempio. 'template T x (const Vector & v);' –
Possibile, ma 'vx()' ha più senso per me di 'x (v)'. Inoltre, mi piacerebbe aggiungere alcuni costruttori specializzati, ad esempio 'Vector (T, T) ', ei costruttori non possono essere funzioni libere –
Thomas
No, ma puoi avere funzioni che restituiscono gli oggetti in base al valore nello stile di' std :: make_pair'. –