Template: Trick: *.h und *.cpp



  • Ich habe irgendwann eine FDrage hier im Forum gestellt und ide ANtwort war:' Nein es ist nicht möglich bei Templates header und cpp zu separieren'
    EIn KOllege hat einen Umweg gefunden und ich dachte das zu Diskussion zu stellen im Forum:

    Also die Lösung wäre: am ENde im cpp Datei, nach der Implementierung aller Funktionen macht man eine explizite Instanziierung für alle statischen Funktionen und alle Datentypen die man in Verbindung mit der Template benutzen möchte und es funktioniert...es ist vielleicht nicht so ellegant aber dafür hat man die *.h-Dateien und *.Cpp-Dateien getrennt.

    ZUM BEISPIEL

    // Explicit instanziation
    template class CVector3<int>;
    template CVector3<int> operator* ( const int, const CVector3<int>& );
    template CVector3<int> operator* ( const CVector3<int>& lhs, const CVector3<int>& rhs );
    template CVector3<int> operator/ ( const CVector3<int>& lhs, const CVector3<int>& rhs );
    
    template class CVector3<float>;
    template CVector3<float> operator* ( const float, const CVector3<float>& );
    template CVector3<float> operator* ( const CVector3<float>& lhs, const CVector3<float>& rhs );
    template CVector3<float> operator/ ( const CVector3<float>& lhs, const CVector3<float>& rhs );
    
    template class CVector3<double>;
    template CVector3<double> operator* ( const double, const CVector3<double>& );
    template CVector3<double> operator* ( const CVector3<double>& lhs, const CVector3<double>& rhs );
    template CVector3<double> operator/ ( const CVector3<double>& lhs, const CVector3<double>& rhs );
    


  • Wenn du genau weißt, daß du das Template nur mit diesen drei Datentypen verwenden willst, ist das gar kein Problem - aber sobald irgendwer auf die Idee kommt, einen CVector3<long> oder CVector3<MyInt> anzulegen, steht der Linker wieder vor dem alten Problem "wo ist die Implementation von operator*(long,const Vector3<long>&)?"



  • Es ist halt ein anderes Instanziierungs-Modell.

    So bist du in der Pflicht, alle Instanziierungen in diese Datei zu schreiben, bzw. in irgendeine Übersetzungseineit, die dann dazu gelinkt wird.

    Dafür hast du die Kontrolle darüber, was wann wo instanziiert wird. Nützlich falls der Compiler in jeder Übersetzungseinheit das Template XY neu instanziiert. (was er wohl dürfte, auch wenn das sicher nicht die ruhmreicheste Implementierung wäre) Ebenfalls nützlich, falls du nicht willst, dass das Template für Typ AB instanziiert wird.



  • JA! das ist der einzige Nachteil...jedesmal wenn ein neues Datentyp habe, muss ich dieses Teil der expliziten Instaziierung erweitern...



  • Danke 7H3N4C3R! Es ist eine sehr gute Erklärung für mich!



  • Falls du tief in die Materie einsteigen willst, kann ich dir dieses Buch hier empfehlen. Es ist allerdings recht anspruchsvoll und nicht unbedingt günstig. Lies am besten mal die Rezension von Marc++us.

    ~klick mich~
    C++ Templates | ISBN: 0201734842



  • Danke für die Buchempfelung! Ich habe das Buch und ich habe auch anderen 3 Bücher von Josuttis. Very good ist auch ...The C++ Standard Library.

    JA! SEite 159 im Buch C++ Templates von Josuttis ist es alles mit explicit instatiation...DANKE Ich habe das Buch aber ich habe nicht richtig da rein geschaut.
    CIAO



  • Falls man sich eh schon auf festgelegte Datentypen einigt, könnte man es doch so machen:

    #define DEFINE_TEMPLATE_CLASS_FOR_TYPE(type) \
    template<type> void my_class::abc(type a) { ...; }
    template<type> void my_class::xyz(type x) { ...; }
    
    DEFINE_TEMPLATE_CLASS_FOR_TYPE(int);
    DEFINE_TEMPLATE_CLASS_FOR_TYPE(float);
    DEFINE_TEMPLATE_CLASS_FOR_TYPE(double);
    DEFINE_TEMPLATE_CLASS_FOR_TYPE(MyOwnFrickeledClass);
    

    o.O



  • Hallo,
    dann würde ich doch eher zum Instantiator-Idiom von Eric Niebler raten.
    http://www.cuj.com/documents/s=8683/cuj0310niebler/
    Eine Uraltversion gibt es hier:

    http://www.geocities.com/eric_niebler/instantiator.html


Anmelden zum Antworten