Klassentemplate Memberfunktionen in cpp definieren

Aloisia

Mitglied
Ich habe eine Klasse TPoly (ein generisches Polynom) in TPoly.h deklariert.
C++:
//TPoly.h
template<typename Ring> class TPoly{...};
Mein Polynom speichert die Koeffizienten in einem Array. Dieses Array muss bei Bedarf (wenn weitere Koeffizienten hinzugefügt werden) vergrößert werden.
dazu habe ich eine
C++:
//TPoly.h
void resize();
Funktion deklariert. Die Definition soll jetzt aber nicht inline in dem Header erfolgen, sondern außerhalb in einer TPoly.cpp.

Einer meiner Versuche sieht folgendermaßen aus:
C++:
//TPoly.cpp
template<typename Ring> void TPoly<Ring>::resize(){...}

Leider identifiziert der Compiler diese Definition nicht mit der Deklaration in TPoly.h
Was mache ich falsch?
 
Hallo,
soweit ich weiß kann man Templates nur in der *.h definieren. Warum das aber so ist kann ich dir nicht genau sagen, habe ich wieder vergessen. Aber probier mal aus die Methode in der *.h zu definieren.

Grüße
 
In der *.h funktioniert es, ich habe alle Funktionen zuerst dort definiert, um sie zu testen, aber ich möchte/muss die Definition auslagern.
Ich habe hier unter "Definition von Memberfunktionen außerhalb der Klasse" das Konstrukt
C++:
template <typename T> RTYP CLASS<T>::MNAME(....)
gesehen. Außerdem habe ich ähnliche Beispiele in meinem Skriptum zur Vorlesung. Es sollte also möglich sein.
 
Hi,
ich habe mal Goggle bisschen beschäftigt. Vielleicht hilft dir hier Punkt 35.12-35.14 weiter? Mehr weiß ich auch nicht :D
Grüße
 
Vielen Dank, das hat mir weitergeholfen. Wenn ich die Definitionen nach dem Semikolon der Klasse (
class foo{ ... }; //Hier her
schreibe geht es. Vielleicht kann man das noch ein bisschen verbessern, ich arbeite mit Visual Studio 2012 Professional.
 
Templates können nicht in eine externe Kompiliereinheit ausgelagert werden. Grund dafür ist, dass ein Template kein compilierbarer Code ist bis du festlegst, mit was es verwendet werden soll. Im Gegensatz zu Java oder .NET sind Templates in C++ effektiv eigentlich nur eine etwas schönere und flexiblere Variante eines Präprozessormakros während in den ersten Umgebungen Generics verwendet werden, die auch bereits ohne die konkrete Typenangabe kompilierbar sein müssen und du daher nur das verwenden kannst, was du bereits zu Kompilierzeit weisst.

Ein einfaches Beispiel:
Nehmen wir an du hast die Klasse Ration die einen operator + definiert.
C++:
template<typename T>
T add(T v1, T v2) { return v1 + v2; }

add<int>(2, 3);
add<Rational>(r1, r2);

Der erste Aufruf wird zu:
Code:
mov eax, [ebp + 8] ; vorausgesetzt add wird in einer Funktion ausgeführt und 2 ist deren erster Parameter
mov ecx, [ebp + 12] ; vorausgesetzt add wird in einer Funktion ausgeführt und 3 ist deren zweiter Parameter
add eax, ecx

Der zweite Aufruf wird zu:
Code:
lea ecx, ebp + 8 ; vorausgesetzt add wird in einer Funktion ausgeführt in der r1 das erste Argument ist
lea eax, ebp + 12 ; wie oben, aber r2 ist das zweite Argument
push eax
call Ration::operator+(const Rational&)

Obwohl der Code zwar ähnlich ist ist er dennoch nicht gleich. Objektcode kann also erst generiert werden, wenn bekannt ist mit was der Compiler T ersetzen soll (wenn es T heisst).

Aus diesem Grund muss jeder, der deine Template-Klasse/-Funktion verwenden will die gesamte Deklaration inklusive Implementation sehen können. Eine Möglichkeit einer "Auslagerung" ist es anstatt in einer C++-Datei die Implementation im Header unter der Klasse zu machen so wie du es gemacht hast, eine andere ist es normal in .h und .cpp aufzuteilen und überall wo du es verwenden willst die .cpp zu inkludieren statt die .h.
 
Ich glaube ich hatte einen Denkfehler. Will ich eine extra cpp, dann muss ich in jedem File, das TPoly.h included auch TPoly.cpp includen... So war das gemeint.
Ich hatte angenommen du meinst ich muss in der TPoly.h auch die TPoly.cpp inkludieren.
 
Zurück