spezifischer Konstruktor für Template-Klasse
-
Ich habe für einen speziellen Zweck eine Template-Klasse für einen n-dimensionalen Vektor geschrieben (dasss die Bezeichnung Vector etwas ungünstig ist, weil die entsprechende Klasse aus der STL genauso, nur in klein heißt, soll mal nicht stören.
Auszug:
template < unsigned int dim > class Vector { public: float x[dim]; // zahlreiche Funktionen }Nun wollte ich einen Konstruktor erstellen, um einen 3D-Vektor zu erzeugen (2,3 und 4-dimensionale Vektoren brauche ich am meisten).
Also versucht in die Klasse zu schreiben:
Vector < 3 > (float in_x0, float in_x1, float in_x2);und enstsprechend in der cpp-Datei:
Vector::Vector < 3 > (float in_x0, float in_x1, float in_x2) { x[0]=in_x0; x[1]=in_x1; x[2]=in_x2; }Auch mein zweiter Ansatz:
template < unsigned int dim > Vector < 3 >::Vector(float in_x0, float in_x1, float in_x2);und in der cpp-Datei:
template <unsigned int dim > Vector<3>::Vector (float in_x0, float in_x1, float in_x2) { x[0]=in_x0; x[1]=in_x1; x[2]=in_x2; }(funktionierte auch nicht, als ich das "template <unsigned int dim >" wegließ).
ging daneben.
Alles gibt Compile-Fehler. Daher: könnte mir jemand erklären, wie ich es richtig mache?
Daher bitte ich euch um Hilfe.
Mit herzlichem Dank
Wolfgke
-
Wenn du ein Template spzialisierst, mußt du dem Compiler zwar sagen, daß das eine Template-Klasse sein soll, aber du mußt die Parameter nicht wiederholen:
template<unsigned int dim> class Vector { // allgemeine Operationen } template<> class Vector<3> { // Operationen für 3D-Vektoren } //wichtig: alle allgemeinen Vektor-Operationen mußt du auch neu definieren //Alternative: class Vector3D : public Vector<3> { // Operationen für 3D-Vektoren } //der erbt die allgemeinen Operationen von Vector<..>
-
Sieht schonmal ganz gut aus.
Lediglich warum muss ich für
template<> class Vector<3>auch die allgemeinen Operationen nochmal definieren?
(die Vererbung würde ich persönlich sowohl aus strukturellen (eine Konvertierung von Vektoren verschiedener Dimensionen soll möglichst einfach möglich sein) als auch aus Performance-Gründen (den Code, den ich erstelle ist sehr rechenaufwändig und plane ich außerdem in einem Spiel einzusetzen) eher ablehnen).
Sollte C++ nicht intelligent genug sein, von selbst zu erkennen, dass 3 ein Spezialfall von einem "unsigned int" darstellt?
-
Sollte C++ nicht intelligent genug sein, von selbst zu erkennen, dass 3 ein Spezialfall von einem "unsigned int" darstellt?
Aus deiner Sicht ist es ein Spezialfall, aber für C++ ist es ein neuer Typ. Da wirst nicht drumrumkommen...
-
Wolfgke schrieb:
Sieht schonmal ganz gut aus.
Lediglich warum muss ich für
template<> class Vector<3>auch die allgemeinen Operationen nochmal definieren?
Weil C++ davon ausgeht, daß du die Spezialisierung aus gutem Grund geliefert hast - und ehe es die Default-Operationen auf einer möglicherweise speziell angepassten Datenstruktur loslaufen lässt, blockt es lieber gleich ab (stell' dir doch mal vor, du implementierst den allgemeinen Vektor mit einem double-Array, den 3D-Vektor allerdings mit drei Membern x,y und z - und dann versuch einen Array-Zugriff ohne Array durchzuführen)
(die Vererbung würde ich persönlich sowohl aus strukturellen (eine Konvertierung von Vektoren verschiedener Dimensionen soll möglichst einfach möglich sein) als auch aus Performance-Gründen (den Code, den ich erstelle ist sehr rechenaufwändig und plane ich außerdem in einem Spiel einzusetzen) eher ablehnen).
Wenn's dir um die Konvertierbarkeit geht, solltest du lieber keine Templates einsetzen - Vector<3> ist für C++ komplett inkompatibel zu (z.B.) Vector<5>, solange du keine expliziten Konvertierungsoperatoren einbaust.
Sollte C++ nicht intelligent genug sein, von selbst zu erkennen, dass 3 ein Spezialfall von einem "unsigned int" darstellt?
Ist es doch auch, deswegen brauchst du das "unsigned int" bei der Spezialisierung auch nicht mehr.
-
@CStoll
Danke, damit sind meine Fragen bezüglich dieses Themas geklärt.