export bei Templates



  • Und wie geht es trotzdem anders?

    Kann ich dem Compiler nicht sagen, dass er einfach das Template dreimal instantiieren soll und keine weiteren Instantiierungen erlauben soll? Die drei entstehenden Klassen kann er dann ja getrennt in den DLL schreiben...

    ChrisM



  • wenn du nur 3 instanzen brauchst, dann mach es mit copy&paste

    ein template ist nur dann ein template wenn es zur compiletime ausgewertet wird. das ist aber nicht gegeben wenn das template nicht im source code vorliegt.

    export ist nur dafuer da um eine trennung zwischen interface und implementation zu erhalten.

    deshalb gibts auch kaum einen compiler der export unterstuetzt, weil es ein feature ist, ohne dem man sehr gut leben kann.



  • Kann ich dem Compiler nicht sagen, dass er einfach das Template dreimal instantiieren soll und keine weiteren Instantiierungen erlauben soll?

    Sicher.
    Du packst die Klassendefinition in eine h-Datei:

    // in h-Datei
    template <class T>
    struct Foo
    {
    public:
        void bla();
    // ...
    };
    

    Baust dir eine cpp-Datei in der du die Methoden definiertst und die Klasse dreimal explizit instanziierst:

    // in cpp-Datei
    #include "foo.h"
    template <class T>
    void Foo<T>::bla() {}
    
    // Instanziieren für int, double, float
    template class Foo<int>;
    template class Foo<double>;
    template class Foo<float>;
    

    Compilierst das ganze zu einer Objekt-Datei oder Bibliothek und lieferst von nun an nur den Header mit.

    Jeder der jetzt versucht das Template mit einem anderen Typen zu instanziieren, wird einen Linkerfehler erhalten.



  • Achso, falls du einen Compilezeit-Schutz haben willst, wird's natürlich ein klein bischen komplizierter. Imo lohnt der Aufwand aber auch nicht.



  • Danke, wird getestet!

    ChrisM



  • was ist ein "Compilezeit-Schutz "?



  • was ist ein "Compilezeit-Schutz "?

    Ich sage:

    Foo<Bar> fooBar;
    

    Der Compiler sagt:
    Concept-Check-Error: Foo kann nicht mit Bar instanziiert werden.

    Oder auch:
    Static-Assert-Error: Foo<Bar> ungültiger Typ.

    Oder wie auch immer. Halt ein Fehler, der bereits durch den Compiler ausgespuckt wird.



  • So, hab das jetzt auf deine Weise bei Vector3, Matrix44 und Rect implementiert. Da hat meine DLL doch gleich mal ca. 100 Exporte mehr 😃

    Aber das mit dem Compilezeit-Schutz hab ich auch noch nicht verstanden, wenn ich versuche, Foo z.B. mit char zu initiieren, kriege ich doch dann auch gleich vom Linker einen nicht aufgelösten Verweis, oder?

    Wenn ich wirklich vom Compiler einen Fehler will, muss ich doch dann nur sowas machen, oder?
    -> http://www.zfx.info/DisplayThread.php?TID=8446

    ChrisM



  • eben, linker. die sind meist wesentlich raetselhafter als compiler errors.



  • Wenn ich wirklich vom Compiler einen Fehler will, muss ich doch dann nur sowas machen, oder?

    Konzeptionell ja. Der Code dort ist allerdings nicht Standard konform.



  • Wieso?

    ChrisM



  • Wieso?

    Spezialisierungen sind nur im Namespace-Scope erlaubt. Nicht im class-Scope.
    Außerdem redeklariert er T im inneren Scope. Das ist bei Templateparameter auch nicht zulässig.


Anmelden zum Antworten