Templates, Linkerfehler und export



  • Hallo.

    Ich bin gerade dabei eine Template Klasse zu schreiben. Deklaration und Definition sind in versch. Übersetzungseinheiten. Sobald ich eine Memberfunktion der Klasse aufrufe, bekomme ich einen Linkerfehler.

    Ich habe dann mal im Struppi-Buch nachgesehen und dort stand, dass man das Schlüsselwort export einsetzen muss. Naja, das wollte ich auch machen, aber Visual C++ kennt das Schlüsselwort export irgendwie nicht 🙄 😞 .

    Könntet ihr mir kurz zeigen wie man das richtig macht mit einer Template Klasse die in versch. Übersetzungseinheiten verteilt ist.



  • wenn export nicht klappt, dann mach die template-definition in den header rein.



  • Danke, ich werds mal machen.
    Dev-C++ kennt export aber auch nicht. 🙄



  • Jetzt wirds strange.

    Datei_1.h:

    template<typename T>
    class Foo
    {
    	T bar;
    
    public:
    	Foo(const T& bar_);
    	~Foo();
    
    	T getBar() const;
    };
    
    template<typename T>
    T Foo<T>::getBar() const
    {
    	return bar;
    }
    
    template<typename T>
    Foo<T>::Foo(const T& bar_)
    : bar(bar_)
    {}
    
    template<typename T>
    Foo<T>::~Foo()
    {}
    

    Datei_1.cpp:

    #include <iostream>
    using namespace std;
    
    #include "Datei_1.h"
    
    int main()
    {
    	Foo<float> goo(4.5f);
    
    	cout << goo.getBar();
    
    	return 0;
    }
    

    Funktioniert.

    Wenn ich das mit meiner Template Klasse mache, dann schmeisst er einen Linkerfehler für jeden Memberfunktionsaufruf in main aus.



  • Jover schrieb:

    Jetzt wirds strange.

    Datei_1.h:

    template<typename T>
    class Foo
    {
    	T bar;
    
    public:
    	Foo(const T& bar_);
    	~Foo();
    
    	T getBar() const;
    };
    
    template<typename T>
    T Foo<T>::getBar() const
    {
    	return bar;
    }
    
    template<typename T>
    Foo<T>::Foo(const T& bar_)
    : bar(bar_)
    {}
    
    template<typename T>
    Foo<T>::~Foo()
    {}
    

    Datei_1.cpp:

    #include <iostream>
    using namespace std;
    
    #include "Datei_1.h"
    
    int main()
    {
    	Foo<float> goo(4.5f);
    
    	cout << goo.getBar();
    
    	return 0;
    }
    

    Funktioniert.

    Wenn ich das mit meiner Template Klasse mache, dann schmeisst er einen Linkerfehler für jeden Memberfunktionsaufruf in main aus.

    Edit: _Wow_: Wenn ich das mache was volkard vorgeschlagen hat, und es in VC++ 6 kompiliere gehts. 😮
    Dev-C++ hat sich beschwert.

    Edit2: Zu dumm zum editieren 🙄 🤡



  • Jover schrieb:

    Dev-C++ hat sich beschwert.

    Was sagt er denn?



  • Naja, Linkerfehler eben. Aber ich glaube, dass dieses Problem auf meine Unkompetenz zurückzuführen ist.
    Im VC++ ist es ja auch gegangen.

    Viel mehr würde es mich interessieren warum er das mit dem export nicht schluckt.
    VC++ interpretiert export z.B.: als globale Variable. 🙄

    Edit: Hier ein kleines Bsp:

    // Datei.h
    template<class T>
    class Foo
    {
    	T bar;
    
    public:
    	void setBar(const T& bar_);
    	T getBar() const;
    };
    
    // Datei.cpp
    #include "Datei.h"
    
    export template<class T>
    void Foo<T>::setBar(const T& bar_)
    {
    	bar = bar_;
    }
    
    export template<class T>
    T Foo<T>::getBar() const
    {
    	return bar;
    }
    
    // main.cpp
    #include <iostream>
    using namespace std;
    
    #include "Datei.h"
    
    int main()
    {
    	Foo<double> bar;
    
    	bar.setBar(123.456);
    
    	cout << bar.getBar();
    
    	return 0;
    }
    

    Das geht nicht. Hab ich nen Fehler gemacht?

    Edit2: Diese Fehler wirft er aus:

    D:\Programme\Microsoft Visual Studio\MyProjects\test\impl.cpp(3) : error C2143: Syntaxfehler : Fehlendes ';' vor ''template<''
    D:\Programme\Microsoft Visual Studio\MyProjects\test\impl.cpp(3) : error C2501: 'export' : Fehlende Speicherklasse oder Typbezeichner
    D:\Programme\Microsoft Visual Studio\MyProjects\test\impl.cpp(9) : error C2143: Syntaxfehler : Fehlendes ';' vor ''template<''
    D:\Programme\Microsoft Visual Studio\MyProjects\test\impl.cpp(9) : error C2501: 'export' : Fehlende Speicherklasse oder Typbezeichner
    D:\Programme\Microsoft Visual Studio\MyProjects\test\impl.cpp(9) : error C2086: 'export' : Neudefinition
    


  • Die template-Definition ist ja eigentlich class {...}, oder?
    Oder gilt das jetzt nur für normale Klassen?

    Egal, jedenfalls muss das, was es jetzt auch immer ist, von der cpp-Datei in die h-Datei, die cpp-Datei dazu darf gar nicht existieren. 🙂

    MfG MAV



  • export wird AFAIK nur vom Comeau Compiler unterstützt.



  • Heist das, dass ich bei einer Template Klasse alles in die .h, .hpp Datei schreiben muss? (Wenn ich z.B.: VC++ verwende)



  • wenn du zwei dateien hast (.h und .cpp) müssen beide in der main eingebunden werden.



  • cof schrieb:

    wenn du zwei dateien hast (.h und .cpp) müssen beide in der main eingebunden werden.

    Nein. Man bindet niemals eine .cpp-Datei ein, man gibt sie beim Linken mit an.

    Heist das, dass ich bei einer Template Klasse alles in die .h, .hpp Datei schreiben muss? (Wenn ich z.B.: VC++ verwende)

    Ja.


Anmelden zum Antworten