Linken bei Template-Klassen
-
Hallo,
ich bekomme das hier einfach nicht erfolgreich ausgeführt.
Wenn ich das als Klasse ohne Template schreibe und direkt mit int arbeite, funktioniert es wunderbar, aber mit dem hier gezeigten Code bekomme ich diese Fehlermeldung:obj\Release\main.o:main.cpp:(.text.startup+0x1e)||undefined reference to `Test<int>::Test(int)'
Was übersehe ich hierbei?
//main.cpp #include "test.h" int main() { Test<int> a(2); return 0; }//test.h #ifndef TEST_H #define TEST_H template<class T> class Test { private: T m; public: Test(T); }; #endif//test.cpp #include "test.h" template<class T> Test<T>::Test(T m) { this->m=m; }
-
Templates müssen komplett im Header implementiert werden.
-
okay, danke!
Warum muss das so?
-
weil das einfach nicht implementierbar ist. Überleg dir mal, wie compilieren funktioneirt:
Der Compiler schaut sich jede cpp einzeln an und verarbeitet sie zu objekt-Dateien(assembler code). Wenn in test.cpp die Definition steht, aber erst in main.cpp klar ist, für welchen Typ die Funktion erzeugt werden muss, dann hat der Compiler zu keinem Zeitpunkt die benötigten Informationen um den source in Objektdateien umzuwandeln -> geht nicht.
In der Tat gab es einmal das export keyword für templates, das genau das erlaubt hat. Das war aber ein riesiger Schuss in den Ofen.
-
Weil der Compiler die Definition des template kennen muss damit er es instanzieren kann.
-
Vielen Dank
Ist verständlich.
-
Warum? Weil die ODR das so sagt!
-
krümelkacker schrieb:
Warum? Weil die ODR das so sagt!
Nö, die sagt nur, dass Templates in mehreren ÜEs definiert sein dürfen, und unter welchen Bedingungen das zu geschehen hat.
Das Problem des OP ist eher, dass er nirgendwo die besagte Funktion instanziiert hat, wo die Definition des Templates sichtbar war. Ich habs nicht genau aus dem Standard lesen können, aber evtl. muss die Definition sogar überall dort sichtbar sein, wo die Memberfunktion instanziiert wird. Das stünde dann irgendwo in §14.7.X