Nicht aufgelöstes externes Symbol bei Template Funktion



  • ich hab eine klasse erstellt um mit dem windows api konsolenausgaben durchzuführen, weil das mit cout nicht geht. die ausgabe und auch der überladene << operator funktionieren, aber wenn ich beim operator templates benutzen will geht es nicht.
    zum schreiben in konsole hab ich diese funktion:

    template <typename T>
    void cout::write(T arg)
    {
    	ostringstream str; 
        str<<arg;
    	  WriteConsole(hStdOut, str.str().c_str(),strlen(str.str().c_str()),&dwwritten, NULL);
    }
    

    die funktioniert so, aber bei der operator funktion

    template <typename T>
    cout& operator<<(cout& c, T str)
    {
    	c.write(str);
    	return c;
    }
    

    kommen immer diese fehler:
    error LNK2001: Nicht aufgelöstes externes Symbol ""class cout & __cdecl operator<<<char const *>(class cout &,char const *)" (???6PBD@@YAAAVcout@@AAV0@PBD@Z)". error LNK2001: Nicht aufgelöstes externes Symbol ""public: void __thiscall cout::write(int)" (??write@H@cout@@QAEXH@Z)".

    wo liegt der fehler?


  • Mod



  • Was ist cout denn für ein Typ? (std::cout ist eine Variable vom Typ std::ostream).

    In welchen Dateien hast du die beiden Funktionstemplates denn defninert? Im Header oder in der .cpp? Siehe dazu auch hier: http://www.c-plusplus.net/forum/246875 (dritter Punkt) und hier: http://www.c-plusplus.net/forum/39467



  • die funktionen direkt in der header datei zu definieren hat das problem wohl gelöst. ich dachte man könnte cout irgendwie ableiten und nur die methoden für die ausgabe ändern um die formatierungsoptionen und so noch beizubehalten, hab keine möglichkeit dafür gefunden.


  • Mod

    cout ist keine Klasse. cout ist ein Objekt vom Typ ostream.



  • Du hast die eine Klasse gebaut, die "cout" heißt?
    Sicher, dass das eine gute Idee ist?
    Es gibt ja schon das Objekt namens cout vom Typ ostream.

    Der Fehler sieht nach einer Missachtung der ODR aus (one definition rule).
    Punkt 5 der FAQ passt doch dazu, nicht?

    Und so am Rande...

    Nikolai schrieb:

    template <typename T>
    void cout::write(T arg)
    {
        ostringstream str; 
        str<<arg;
        WriteConsole(hStdOut, str.str().c_str(),strlen(str.str().c_str()),&dwwritten, NULL);
    }
    

    Warum so kompliziert? Du holst dir 2mal ein Stringobjekt ab und willst dann noch per strlen die Länge berechnen. Was hältst du von...

    template <typename T>
    void cout::write(T const& arg)
    {
        using namespace std;
        ostringstream str; 
        str << arg;
        string s = str.str();
        WriteConsole(hStdOut, s.c_str(), s.length(), &dwwritten, NULL);
    }
    

    ?


Log in to reply