Template in Klasse ohne Klassentemplate
-
Hi everyone
Kann ich eine Template-Memberfunktion erstellen, ohne dabei ein Klassentemplate draus zu machen?
Ich möchte eine Memberfunktion meiner Klasse explizit mit einem Typnamen angegeben aufrufen lassen, etwa so:
class CEwbOutput { // ... public: template <typename T> void otp_LPEx2(std::vector<CEwbMeter *>::const_iterator, std::vector<CEwbMeter *>::const_iterator) const; // ...Die Klasse selbst ist also keine Template-Klasse, hat aber eine Template Memberfunktion. Der Compiler lässt mir das so durchgehen, der Linker allerdings reklamiert beim folgenden Aufruf:
stdOtp.otp_LPEx2<CEMeter>(ewbArray.begin(), remove_if(ewbArray.begin(), ewbArray.end(), otPred));Und zwar mit der Meldung:
: undefined reference to `void CEwbOutput::otp_LPEx2<CEMeter>(__gnu_cxx::__normal_iterator<CEwbMeter* const*, std::vector<CEwbMeter*, std::allocator<CEwbMeter*> > >, __gnu_cxx::__normal_iterator<CEwbMeter* const*, std::vector<CEwbMeter*, std::allocator<CEwbMeter*> > >) const'Gehen also Template-Members ohne Template-Klassen gar nicht oder habe ich da sonst was verbockt
?Thx schon im Voraus und greeetz
Kessi
-
Das geht schon. Aber so wie's aussieht kann der Linker deine Implementierung nicht finden. Bist Du Dir der Tatsache bewusst, dass die Implementierung einer Template-Funktion *ebenfalls* in die Header-Datei muss? In einer cpp-Datei findet sie der Linker nicht.
-
Außerdem verwendet die Methode gar nicht den Template-Parameter 'T'.
Es müßte also so deklariert werden:class CEwbOutput { // ... public: template <typename T> void otp_LPEx2(std::vector<T*>::const_iterator, std::vector<T*>::const_iterator) const; // ...
-
Th schrieb:
Es müßte also so deklariert werden:
class CEwbOutput { // ... public: template <typename T> void otp_LPEx2(std::vector<T*>::const_iterator, std::vector<T*>::const_iterator) const; // ...Da fehlen zwei typenames.
-
Zusammenfassend:
AusKessiMC schrieb:
class CEwbOutput { // ... public: template <typename T> void otp_LPEx2(std::vector<CEwbMeter *>::const_iterator, std::vector<CEwbMeter *>::const_iterator) const; // ...müsste werden:
template <typename T> void otp_LPEx2(typename std::vector<T *>::const_iterator, typename std::vector<T *>::const_iterator) const { // Implementierung }
-
Konrad Rudolph schrieb:
Das geht schon. Aber so wie's aussieht kann der Linker deine Implementierung nicht finden. Bist Du Dir der Tatsache bewusst, dass die Implementierung einer Template-Funktion *ebenfalls* in die Header-Datei muss? In einer cpp-Datei findet sie der Linker nicht.
Ah, ah, ah, stiiimmt... Daran hat's gelegen. Der Parameter T wird übrigens zum casten innerhalb der Methode verwendet.
Thx und greeetz
Kessi
-
Nur so nebenbei: man muss Template Parameter nicht verwenden, ein
template <class T, class U> void foo() {}ist schon vollkommen OK.
Visual C++ 6 ist halt wieder mal zu doof um damit umzugehen, aber grundsätzlich ist nix daran auszusetzen.
-
hustbaer schrieb:
Nur so nebenbei: man muss Template Parameter nicht verwenden, ein
template <class T, class U> void foo() {}ist schon vollkommen OK.
Visual C++ 6 ist halt wieder mal zu doof um damit umzugehen, aber grundsätzlich ist nix daran auszusetzen.In diesem Fall müssen beim Aufruf von foo die Typen, die für T und U eingesetzt werden sollen, explizit angegeben werden - und hier wird's beim VC 6.0 eng. explicit template argument specification unterstützt der VC 6.0 nur für freie Funktionen. Die Synatx obj.memberTemplate<x, y, z>() hingegen, versteht dieser ältere Compiler nicht.