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:
    Aus

    KessiMC 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.


Anmelden zum Antworten