Visual C++ 2005 EE sagt mir bei multiset-iterator irgendwas mit Tree...



  • Hallo Zusammen.
    Habe folgendes Problem.
    Habe mir eine Klasse geschrieben, die Highscore-Einträge in einem Spiel verwaltet, diese Einträge packe ich dann in einen multiset-container, um so die Highscore zu realisieren.
    Hier ist die Klasse für die Einträge und die Funktion zum Schreiben in eine Datei:

    class HighscoreEntry
    {
    	public:
    		HighscoreEntry(void);
    		HighscoreEntry(const std::string &name, int points);
    		~HighscoreEntry();
    
    		std::string const& get_name() const;
      		void set_name(std::string const& name); 
    
    		void set_points(int points);
    		int get_points(void) const;
    
    	private:
    		std::string m_name;
    		int m_points;
    };
    
    inline bool operator <(HighscoreEntry const &left, HighscoreEntry const &right)
    {
      return (left.get_points() == right.get_points() ?
               left.get_name().compare(right.get_name()) < 0 :
               left.get_points() < right.get_points());
    };
    
    typedef std::multiset<HighscoreEntry> Highscore; 
    
    void write_highscore(std::string const &path, Highscore const &myHighscore)
    {
    	HighscoreEntry Entry;
    	Highscore::iterator it;
    	std::fstream HighscoreFile;
    	std::ostringstream Str;
    	std::string EntryString;
    	std::string output;
    	char character;
    	char key = 'z';
    
    	HighscoreFile.open(path.c_str(), std::fstream::out);
    
      	HighscoreFile.clear();
    
    	for(it=myHighscore.begin();it!=myHighscore.end();it++)
    	{
    		EntryString.clear();
    		output.clear();
    		Str.str("");
    		Str.clear();
    		Entry = *it;
    		EntryString += Entry.get_name();
    		EntryString += "#";
    		Str << Entry.get_points();
    		EntryString += Str.str();
    		for(unsigned int i=0;i<=EntryString.length();i++)
    		{
    			character = EntryString[i] ^ key;
    			output += character;
    		};
    		HighscoreFile << output << std::endl;
    	};
    	HighscoreFile.close();
    };
    

    Unter Linux mit g++ kompiliert er mir alle ohne Probleme, nur wollte ich das nun in Visual C++ 2005 EE in ein Spiele-Projekt einbauen und er gibt mir folgenden Fehler aus:

    error C2679: Binärer Operator '=': Es konnte kein Operator gefunden werden, der einen rechtsseitigen Operanden vom Typ 'std::_Tree<_Traits>::const_iterator' akzeptiert (oder keine geeignete Konvertierung möglich)
    with
    [
    _Traits=std::_Tset_traits<HighscoreEntry,std::less<HighscoreEntry>,std::allocator<HighscoreEntry>,true>
    ]
    c:\programme\microsoft visual studio 8\vc\include\xtree(484): kann 'std::_Tree<_Traits>::iterator &std::_Tree<_Traits>::iterator::operator =(const std::_Tree<_Traits>::iterator &)' sein
    with
    [
    _Traits=std::_Tset_traits<HighscoreEntry,std::less<HighscoreEntry>,std::allocator<HighscoreEntry>,true>
    ]
    bei Anpassung der Argumentliste '(std::_Tree<_Traits>::iterator, std::_Tree<_Traits>::const_iterator)'
    with
    [
    _Traits=std::_Tset_traits<HighscoreEntry,std::less<HighscoreEntry>,std::allocator<HighscoreEntry>,true>
    ]

    Seltsam finde ich auch, dass er mir beim iterator in der Funktion write_highscore folgendes anzeigt:

    Highscore::iterator it
    

    typedef std::_Tree<std::_Tset_trailts<HighscoreEntry, std::less<HighscoreEntry>, std::allocator<HighscoreEntry>, true> >::iterator std::multiset<HighscoreEntry>::iterator

    Was Hat der da mit dem "Tree"?

    Weiß jemand, was ich mit dieser Fehlermeldung anfangen kann?
    Wie kann ich das lösen?

    MfG
    Hundefutter



  • .. dass das mit g++ compiliert kann ich fast nicht glauben. Der Fehler ist eindeutig.

    void write_highscore(std::string const &path, Highscore const &myHighscore)
    {
        HighscoreEntry Entry;
        Highscore::iterator it;   // das ist ein Iterator auf eine nicht const multiset
        // ...
        for(it=myHighscore.begin();it!=myHighscore.end();it++) // myHighscore ist aber const
              //  .. daher liefert myHighscore.begin() einen const_iterator
        {
    

    Korrekt wäre:

    void write_highscore(std::string const &path, Highscore const &myHighscore)
    {
        HighscoreEntry Entry;
        Highscore::const_iterator it;   // das ist ein Iterator auf eine const multiset
        // ...
    

    und besser wäre es die Variablen erst dann zu deklarieren, wenn sie gebraucht werden - also

    void write_highscore(std::string const &path, Highscore const &myHighscore)
    {
        // ...
        for( Highscore::const_iterator it=myHighscore.begin();it!=myHighscore.end(); ++it)
        {
    

    dann sieht man das auch besser.

    Der multiset ist im VS intern als Baumstruktur (Tree) implementiert, daher diese etwas kryptische Typ.

    Gruß
    Werner



  • Vielen Dank für die Verbesserung, jetzt kompiliert er zumindest schon mal ohne Fehler.

    Nun habe ich jedoch ein neues Problem.
    Beim Linken gibt er mir was von einem mehrfach definierten Symbol an:

    main.obj : error LNK2005: "void __cdecl read_highscore(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,class std::multiset<class HighscoreEntry,struct std::less<class HighscoreEntry>,class std::allocator<class HighscoreEntry> > &)" (?read_highscore@@YAXABV?basic_string@DU?basic\_string@DU?char_traits@D@std@@V?allocator@D@2@@std@@AAV?allocator@D@2@@std@@AAV?multiset@VHighscoreEntry@@U?less@VHighscoreEntry@@@std@@V?less@VHighscoreEntry@@@std@@V?allocator@VHighscoreEntry@@@3@@2@@Z) ist bereits in Highscore.obj definiert.
    main.obj : error LNK2005: "void __cdecl write_highscore(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,class std::multiset<class HighscoreEntry,struct std::less<class HighscoreEntry>,class std::allocator<class HighscoreEntry> > const &)" (?write_highscore@@YAXABV?basic_string@DU?basic\_string@DU?char_traits@D@std@@V?allocator@D@2@@std@@ABV?allocator@D@2@@std@@ABV?multiset@VHighscoreEntry@@U?less@VHighscoreEntry@@@std@@V?less@VHighscoreEntry@@@std@@V?allocator@VHighscoreEntry@@@3@@2@@Z) ist bereits in Highscore.obj definiert.
    .\Debug/Memory.exe : fatal error LNK1169: Mindestens ein mehrfach definiertes Symbol gefunden.

    Er sagt, dass in main.obj was definiert wird, was in Highscore.obj schon ist, nur in main.cpp steht nix von read/write_highscore...!

    Woran könnte sowas liegen? Hatte so ein mehrfach definiertes Symbol noch nie...

    MfG
    Hundefutter



  • Inkludierst du evtl die Implementation, also void write_highscore(std::string const &path, Highscore const &myHighscore) {...} ? Übrigens fehlt da ein HighscoreEntry:: , also void HighscoreEntry::write_highscore( ... .

    edit: Ups, alles klar, dachte das wäre eine Funktion von HighscoreEntry.. Naja, um so besser 🙂



  • Ach mit, hast Recht, hatte die Implementation reinkopiert und natürlich falsch, also in die Header-Datei..
    Nehme ich dort die Implementation raus, läuft alles ohne Probleme :).
    Vielen Dank.

    Die Funktion write_highscore ist übirgens nicht Bestandteil der Klasse.
    Die Klasse verwaltet nur die Einträge, die Highscore selber steckt dann in nem multiset...

    MfG
    Hundefutter


Anmelden zum Antworten