Ich schreibe eine einfache mathematische Bibliothek mit einem Template-Vektortyp:
template<typename T, size_t N>
class Vector {
public:
Vector<T, N> &operator+=(Vector<T, N> const &other);
// ... more operators, functions ...
};
Jetzt möchte ich etwas zusätzlich Funktionalität speziell für einige von ihnen. Sagen wir, ich möchte Funktionen x()
et y()
auf Vector<T, 2>
um auf bestimmte Koordinaten zuzugreifen. Hierfür könnte ich eine partielle Spezialisierung erstellen:
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;
};
Aber jetzt wiederhole ich alles, was bereits in der generischen Vorlage vorhanden war.
Ich könnte auch die Vererbung nutzen. Umbenennung der generischen Vorlage in VectorBase
Ich könnte das tun:
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;
};
Das Problem ist nun aber, dass alle Operatoren auf VectorBase
so kehren sie zurück VectorBase
Instanzen. Diese können nicht zugewiesen werden Vector
Variablen:
Vector<float, 3> v;
Vector<float, 3> w;
w = 5 * v; // error: no conversion from VectorBase<float, 3> to Vector<float, 3>
Ich könnte Vector
einen impliziten Konvertierungskonstruktor, um dies zu ermöglichen:
template<typename T, size_t N>
class Vector : public VectorBase<T, N> {
public:
Vector(VectorBase<T, N> const &other);
};
Aber jetzt konvertiere ich von Vector
à VectorBase
und wieder zurück. Auch wenn die Typen im Speicher gleich sind und der Compiler all dies wegoptimieren könnte, fühlt es sich umständlich an, und ich mag es nicht wirklich, potenziellen Laufzeit-Overhead für etwas zu haben, das im Wesentlichen ein Kompilierzeitproblem ist.
Gibt es eine andere Möglichkeit, dieses Problem zu lösen?