Template Klassen in .h und .cpp aufteilen?



  • Hallo 🙂
    Ich lerne seit ca nem Jahr C++ so nebenbei hobbymäßig... Alle Lernbücher usw empfehlen, dass man den Code immer aufteilt in eine header-Datei und eine cpp-datei, nun stoße ich da aber bei Template-Klassen an meine Grenzen:
    wenn ich alles so schön aufteile, wie gelernt, dann kommt in der Testphase mehrfach der Fehler ".. Verweis auf nicht aufgelöstes externes Symbol..." dafür habe ich zwei Lösungen gefunden:
    1. Ich schreibe den Kompletten Code in eine Header-Datei
    2. Ich schreibe für jede mögliche Templateauslegung eine explizite Instantiierung alà:

    template class MeineKlasse<int>; 
    template class MeineKlasse<float>;
    template class MeineKlasse<double>;
    template class MeineKlasse<short>;
    template class MeineKlasse<long>;
    

    die 2. Variante finde ich persönlich blöd, dann könnte ich auch gleich für jede variante ne extra Klasse schreiben...
    Meine Frage wäre, ob es noch eine 3. Möglicheite gäbe, bzw wenn nicht, was der Nachteil dabei ist, alles in eine Datei zu schreiben.



  • Typischerweise ist Methode 1 angesagt - alles im Headerfile.



  • es geht noch folgendes

    template funktions köpfe (sprich die deklarationen) in eine header datei
    und die implementationen in eine cpp datei, die man in xXx.impl umbenennt

    und diese inkludiert man nach den deklarationen in die header datei

    // fkt.h
    template<typename T>
    void swap(T const& a, T const& b):
    // ...
    
    include "fkt.impl"
    
    // fkt.impl
    
    template<typename T>
    void swap(T const& a, T const& b)
    {
        T tmp = a;
        a = b;
        b = a;
    }
    


  • Wie sieht's denn mit den #include Direktiven bei der .impl Version aus?



  • Sorry, meine natürlich die include-guards. Da bin ich mir immer unsicher, wo die überall hingehören.



  • zur not immer dazuschreiben, schaden kanns nicht...



  • danke an alle... ich habs jetzt doch einfach drunter geschrieben...
    aber was ist denn daran jetzt eigentlich der nachteil? also man wird ja eigentlich immer angewiesen den code in 2 seperate dateien zu packen. warum?



  • Skym0sh0 schrieb:

    es geht noch folgendes

    template funktions köpfe (sprich die deklarationen) in eine header datei
    und die implementationen in eine cpp datei, die man in xXx.impl umbenennt

    und diese inkludiert man nach den deklarationen in die header datei

    // fkt.h
    template<typename T>
    void swap(T const& a, T const& b):
    // ...
    
    include "fkt.impl"
    
    // fkt.impl
    
    template<typename T>
    void swap(T const& a, T const& b)
    {
        T tmp = a;
        a = b;
        b = a;
    }
    

    Es fehlt noch ein inline um die ODR nicht zu verletzen.
    Simon



  • theta schrieb:

    Es fehlt noch ein inline um die ODR nicht zu verletzen.
    Simon

    Nope, die ODR greift in der Hinsicht bei Templates nicht - sonst müssten ja alle Funktionstemplates IMMER inline sein. Die ODR für Templates lautet etwas anders als die für normale Symbole: Es dürfen in verschiedenen Übersetzungseinheiten Definitionen für das selbe Template vorhanden sein, allerdings müssen die äquivalent sein.



  • cloud21 schrieb:

    also man wird ja eigentlich immer angewiesen den code in 2 seperate dateien zu packen. warum?

    das liegt zum einen daran dass man seine klassen und funktionen zu bibliotheken compilieren kann
    so hast du dann eine header datei und eine fertig kompilierte lib die du an andere leute weitergeben kannst
    so können die deine funktionen nutzen ohne den quellcode sehen zu können, nur die deklarationen...

    zum anderen geht der compile vorgang viel schneller
    stell dir vor dein programm hat 500 header und 500 cpp dateien, die auch alle genutzt werden. beim compilen parst der compiler zwar alle dateien und erzeugt aus den cpp's dann obj dateien, aber wird eine datei nicht verändert packt der compiler diese auch nicht neu an (ausser beim kompletten rebuild). schreibst du den inhalt der 500 cpp's jetzt aber in die header werden diese natürlich saugroß und der compiler muss diese immer wieder neu parsen, denn die header werden imemr geparst...

    also:
    1.- compilen geht schneller
    2.- du kapselt den code ab vor den augen anderer leute



  • pumuckl schrieb:

    theta schrieb:

    Es fehlt noch ein inline um die ODR nicht zu verletzen.

    Nope, die ODR greift in der Hinsicht bei Templates nicht

    kommt drauf an, was Du unter "ODR" verstehst. Ich verstehe darunter einen ganzen Abschnitt im C++ Standard, der diverse Regeln und Ausnahmen umfasst. Templates werden dabei auch erwähnt. 🙂


Log in to reply