Template aufteilen in *.h und *.cpp
-
Hi,
ist es möglich, dass ich eine template-Definition in 2 Dateien aufteile, wie man es ja auch z.B. bei normalen Klassen machen kann?
Ich habe es z.B. mit:
// .h class Widget { template <typename T> void AddSizeListener(T* o, void (T::* f)(int, int)); }; // .cpp template <typename T> void Widget::AddSizeListener(T* o, void (T::* f)(int, int)) { onSizeListener.push_back((EventCallerSize<Widget>*)new EventCallerSize<T>(o, f)); }
probiert.
Der Compiler meckert nicht, aber der Linker meldet "... undefinded reference ...".Oder ist eine template-Definition grundsätzlich nur in Header-Files möglich?
-
nicht möglich!
-
mantiz schrieb:
Oder ist eine template-Definition grundsätzlich nur in Header-Files möglich?
ja
weil die implementierung für den jeweiligen datentyp immer erst generiert wird,
wenn die templatefunktion mit dem datentyp genutzt wird.
-
mantiz schrieb:
Oder ist eine template-Definition grundsätzlich nur in Header-Files möglich?
Jain.
Prinzipiell gibt es die Möglichkeit vor die Deklaration export zu schreiben, dann geht das was Du vorhast, zumindest theoretisch. Praktisch unterstützt das bis jetzt nur der Comeau-Compiler.
Das Problem ist, daß der Compiler, obwohl er nur die Deklaration des Templates sieht es ja instanziieren muß, wenn er er's benutzen will. Und dazu benötigt er die Definition...
Das einfachste ist wohl die Methoden im Header zu implementieren. Vielleicht ein bißchen ausgefeilter ist es, die Implementierungen in eine Datei DeineKlasse.inl auszulagern und in DeineKlasse.h die Deklaration und am Schluß ein #include "DeineKlasse.inl" reinzuschreiben.
Das macht es einfacher später mal umzustellen.
Das ist mein bevorzugter Weg.Es gibt noch eine dritte Möglichkeit: Du trennst es komplett auf, wie Du es zur Zeit wahrscheinlich auch machst und legste eine cpp-Datei an, die auch die Implementierung mit einbindet und instanziierst dort alle Varianten die Du vom template brauchst explizit. Dadurch kann der Linker sie dann später finden. Allerdings mußt Du dann immer von Hand eintragen was Du alles brauchst, außerdem kannst Du dann das SFINAE-Prinzip nicht so einfach verwenden, da alle Methoden instanziiert werden wenn Du explizit instaniziierst.
MfG Jester
-
Wenn ich mir das so durchlese, dann ist es irgendwie klar, dass es nur in Headern geht. :p
Die Lösung mit dem include im Header wäre da auch eine Möglichkeit, aber da werde ich dann wohl erstmal drauf verzichten, solange es noch übersichtlich bleibt.
Vielen Dank.
-
Um die template-Deklarationen übersichtlich zu halten (besonders bei Klassentemplates) schreibe ich die Defintionen immer in eine ".inl"-Datei (inline) und includiere sie dann in der Header-Datei. Falls irgendwann mehr Compiler das export unterstützen, wären die Änderungen dann nicht soviel.