Methode kann nicht gefunden werden



  • Hallo Leute,

    folgende Frage:

    CSVDocument.h:

    // ...
    template <class TToken> class CSVDocument;
    template <class TToken> std::ostream& operator<<(std::ostream&, const CSVDocument<TToken>&);
    template <class TToken> std::istream& operator>>(std::istream&, CSVDocument<TToken>&);
    
    template <class TToken>
    class CSVDocument
    {
    	public:
    
    		// ...
    
    		friend std::ostream& operator<< <>(std::ostream& out, const CSVDocument<TToken>& document);
    		friend std::istream& operator>> <>(std::istream& in, CSVDocument<TToken>& document);
    
    };
    

    CSVDocument.cpp:

    #include "CSVDocument.h"
    
    using namespace std;
    
    // ...
    template <class TToken>
    ostream& operator<<(ostream& out, const CSVDocument<TToken>& document)
    {
    	// ....
    	return out;
    }
    
    template <class TToken>
    istream& operator>>(istream& in, CSVDocument<TToken>& document)
    {
    	// ...
    	return in;
    }
    
    // ...
    

    $ make CSVDocument.o
    g++ -Wall -c CSVDocument.cpp CSVDocument.h

    Keine Kompilierfehler ­čĹŹ

    Main.cpp

    #include <iostream>
    #include <cstdlib>
    #include <fstream>
    #include <string>
    #include "CSVDocument.h"
    
    const char* DATAFILE = "data.csv";
    
    int main(int argc, char *argv[])
    {
    	using namespace std;
    
    	ifstream input(DATAFILE);
    	if (!input)
    	{
    		cerr << "The data file '" << DATAFILE << "' doesn't exist." << endl;
    		exit(EXIT_FAILURE);
    	}
    
    	CSVDocument<string> document;
    	input >> document;
    
    	input.close();
    
    	return EXIT_SUCCESS;
    }
    

    $ make
    g++ -Wall -c Main.cpp
    g++ -Wall -c PNode.cpp PNode.h
    g++ -Wall -o mrsts CSVDocument.o Main.o PNode.o
    Main.o: In function main': Main.cpp:(.text+0xd3): undefined reference tostd::basic_istream<char, std::char_traits<char> >& operator>><std::basic_string<char, std::char_traits<char>, std::allocator<char> > >(std::basic_istream<char, std::char_traits<char> >&, CSVDocument<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >&)'
    collect2: ld returned 1 exit status
    make: *** [mrsts] Fehler 1

    Fehler ­čĹÄ

    Hinweis: Der Fehler tritt auch bei anderen Methoden auf (nutzen auch den istream), nicht nur bei den operatoren.

    Nach mehreren Stunden beim gleichen Fehler bin ich sehr genervt.
    Ich hatte wirklich Jahre nicht mehr mit C++ zu tun, da ich unter Java "unterwegs" war.

    Habt Ihr eine Idee, wie man das L├Âsen kann.

    Ich w├╝rde mich ├╝ber Eure Hilfe sehr freuen.

    Viele Gr├╝├če ­čÖé



  • Templates und eigenst├Ąndige ├ťbersetzungseinheiten vertragen sich nicht besonders gut - der Compiler will bei Verwendung des Templates die komplette Definition sehen, damit er wei├č, wie er daraus Code erzeugen soll. Die L├Âsung besteht darin, die Funktionen direkt im Header zu definieren (alternativ in einer IMPL-Datei, die am Ende des Headers eingebunden wird).



  • @CStoll

    Vielen Dank f├╝r Deine Antwort ­čÖé
    Das war tats├Ąchlich die L├Âsung.

    Ich habe jetzt auf die Schnelle in der Maindatei die CSVDocument.cpp eingebunden. Wie funktioniert das mit der impl-Datei? Ist das eine cpp mit dem Suffix *.impl? Ist das eine g├Ąngige Konvention?



  • Wie die Dateien hei├čen, die du einbindest ist dem Compiler (bzw. Pr├Ąprozessor) egal, allerdings ist CPP in den meisten Entwicklungsumgebungen f├╝r eine eigenst├Ąndige Quelldatei reserviert (d.h. sie wird versuchen, sie direkt in den Compiler zu f├╝ttern). Deshalb verwendet man f├╝r solche Hilfsdateien wie in deinem Beispiel eine andere Datei-Endung (IMPL wie "Implementation" klingt da recht passend).



  • Falls dein Compiler C++11 (zumindest teilweise) unterst├╝tzt, k├Ânntest du die Templates auch als extern deklarieren:

    template<typename T>
    extern void foo();
    


  • Wenn Methoden nicht gefunden werden, immer erst unter dem stack nachschauen. ­čĄí



  • cooky451 schrieb:

    Falls dein Compiler C++11 (zumindest teilweise) unterst├╝tzt, k├Ânntest du die Templates auch als extern deklarieren:

    template<typename T>
    extern void foo();
    

    Erz├Ąhl doch nicht so einen Quatsch!



  • wird extern nicht nur vom comeau compiler unterst├╝tzt?!?
    und das auch nicht so ganz zufriedenstellend?



  • kr├╝melkacker hat nat├╝rlich recht, das war Quatsch. Entschuldigt.



  • @Skym0sh0: Du hast extern mit export verwechselt.



  • cooky451 schrieb:

    Falls dein Compiler C++11 (zumindest teilweise) unterst├╝tzt, k├Ânntest du die Templates auch als extern deklarieren:

    template<typename T>
    extern void foo();
    

    export statt extern.

    Trotzdem h├Ątte es linu(x)bie nichts geholfen.
    Der Comeau und der Intel Compiler sind die einzigen Compiler, die das exporten von Templates beherrschen.



  • Wusste gar nicht, dass der ICC das auch kann. export ist seit C++11 ├╝brigens kein Standard mehr.



  • dot schrieb:

    Wusste gar nicht, dass der ICC das auch kann.

    http://software.intel.com/en-us/articles/intel-c-compiler-ansi-cc-compliance/ schrieb:

    The export keyword for templates is supported in Intel® C++ Compiler for Linux* 8.1 or newer. It is supported in the Intel® C++ Compiler for Mac OS*.

    But the export keyword for templates is not supported in the Intel® C++ Compiler for Windows or the Intel Parallel Composer.

    dot schrieb:

    export ist seit C++11 ├╝brigens kein Standard mehr.

    Gut zu wissen...!


Log in to reply