Funktion "find(iter,iter,&elem)" mit eigenen Klassen



  • Ich habe folgendes Problem :

    Ich habe einen vector gefüllt mit meinen Objekten meiner selbst geschriebenen Klasse "Unit" und will nun die Funktion find anwenden um ein iterator auf ein bestimmtes Element zu bekommen. Nun sagt mir mein Compiler aber folgendes :

    no matching function for call to ‘find(__gnu_cxx::__normal_iterator<Unit*, std::vector<Unit, std::allocator<Unit> > >, __gnu_cxx::__normal_iterator<Unit*, std::vector<Unit, std::allocator<Unit> > >, Unit&)
    

    Ich vermute es liegt daran das ich den == operator nicht so überladen habe wie der Compiler das gerne hätte, nur sehe/verstehe ich dann meinen Fehler nicht :

    Fraction.cpp

    void Fraction::rm_Unit(Unit u) {
    	std::vector<Unit>::iterator iter = find(troops.begin(),troops.end(),u);
    	if(iter != troops.end())
    		troops.erase(iter);
    }
    

    Unit.hpp

    #ifndef UNIT
    #define UNIT
    class Unit;
    
    inline bool operator==(const Unit&,const Unit&); //einmal den == global, wird in der .cpp definiert
    
    class Unit : public Moveable {
    	UNITTYPE type;  //UNITTYPE ist ein Enum was ich früher definiere
    
            const UNITTYPE get_type() const;	
    
    public:
    	Unit(Stationable*,UNITTYPE);
    	virtual void set_stationed(Stationable*);
    	virtual bool can_stationed(Stationable*);
    
    	inline bool operator==(const Unit&); //einmal == als Elementmethode, wird auch in de .cpp definiert
    
    };
    
    #endif
    

    danke für eure Zeit und Hilfe



  • Hast du <algorithm> inkludiert bzw. using namespace std; in deinem Code?



  • Jetzt bekomm ich folgende Fehler:

    /usr/include/c++/4.4/bits/stl_algo.h:174: error: no match for ‘operator==’ in ‘__first.__gnu_cxx::__normal_iterator<_Iterator, _Container>::operator* [with _Iterator = Productionplace**, _Container = std::vector<Productionplace*, std::allocator<Productionplace*> >]() == __val’
    fraction/../unit/Model_Unit.hpp:10: note: candidates are: bool operator==(const Unit&, const Unit&)
    

    Zwischenfrage: Was ist ein allocator?



  • Reduziere das Problem auf ein kleines vollständiges Minimalbeispiel, welches Du selbst getestest hast und ein unerwartetes Verhalten hat. Zeige uns dieses Minimalbeispiel komplett.



  • #include <algorithm>
    #include <iostream>
    #include <vector>
    
    class a {
    
    public:
      int p;
    
      a(int g) : p(g) {};
    
      inline bool operator==(const a &s) { 
    	if(this->p == s.p)
    		return true;
    	else
    		return false;
    	} 
    };
    
    class b {
    
    public:
     std::vector<a> vec;
    
     b() { 
           a eins(1);
           a zwei(2);
           a drei(3);
           a vier(4);
           a funf(5);
           vec.push_back(eins);
           vec.push_back(zwei);
           vec.push_back(drei);       
           vec.push_back(vier); 
           vec.push_back(funf);
     }
    
     int getOne() {
          std::vector<a>::iterator iter = std::find(vec.begin(),vec.end(),3);
          return (*iter).p;
         }
    
    };
    
    int main() {
    	b theclass;
    
    	int a = theclass.getOne();
    
    	std::cout << a << std::endl;
    }
    

    Das war das simpelste auf das ich es reduzieren konnte, aber es wirft nicht den gleichen Fehler.

    example.cpp:(.text+0x2c): undefined reference to `std::cout'
    example.cpp:(.text+0x31): undefined reference to `std::basic_ostream<char, std::char_traits<char> >::operator<<(int)'
    example.cpp:(.text+0x36): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)'
    ...etc....
    

    €: Fehler korrigiert und ein Haufen neuer Fehlermeldungen, ich habe das Gefühl das das nicht in die Richtung geht das es hilfreich wird. Keiner eine Idee was meinem Ursprünglichem Problem zu Grunde liegt?



  • Da sind dann ja auch noch ne Menge anderer Fehler drin ...

    Warum benutzt du einen std::vector<int>::iterator für einen std::vector<a>? Da muss natürlich immer der gleiche Typ verwendet werden.



  • std::vector<int>::iterator iter = ...;
    // ->
    std::vector<a>::iterator iter = ...;
    

    Und:

    b theclass();
    // ->
    b theobject;
    

    Ausserdem sind eine Menge Vereinfachungen möglich:

    if(this->p == s.p)
        return true;
    else
        return false;
    // ->
    return (p == s.p);
    

    Im Weiteren:

    a eins(1);
    vec.push_back(eins);
    // ->
    vec.push_back(a(1));
    // ->
    vec.push_back(1);
    


  • error: no match for ‘operator==’ in ‘__first.__gnu_cxx::__normal_iterator<_Iterator, _Container>::operator* [with _Iterator = Productionplace**, _Container = std::vector<Productionplace*, std::allocator<Productionplace*> >]() == __val’
    fraction/../area/Model_Productionplace.hpp:20: note: candidates are: bool operator==(const Productionplace&, const Productionplace&)
    

    Wenn mir jemand diesen Compilerfehler übersetzen kann denke ich könnte ich auf die Lösung kommen.



  • Kein passender operator== für verschiedene Iteratortypen. Aber lies die Posts, der Fehler wurde schon zwei Mal genannt.



  • Falls du auf die Fehler in dem Minimalbeispiel ansprichst, das hat sich in keine hilfreiche Richtung entwickelt.
    Wenn es was anderes war stehe ich auf dem Schlauch.

    Welche unterschiedlichen iteratortypen werden denn erwartet? Für mich steht da nur Kauderwelsch und ich habe nicht die leiseste Idee wie ich das "reparieren" soll.



  • Vielleicht solltest du uns ein besseres Codebeispiel bringen, das auch was mit deinem Problem zu tun hat. Sonst müssen wir wieder herumraten.

    Aber grundsätzlich gilt: Du kannst den Operator == nicht auf zwei verschiedene Typen anwenden (ausser es existiert eine entsprechende Überladung oder Konvertierung). Und Iteratoren von zwei verschiedenen Containertypen haben nunmal nicht den gleichen Typ.



  • ich will ihn auch garnicht überladen, ich will lediglich den find Algorithmus auf meinen Vector anwenden, dies setzt aber vor-raus, dass die in dem Vector gespeicherte Klasse den == operator implementiert. Dies habe ich getan. (sh. Code) aber leider ist mein Compiler nicht zufrieden.

    Welche Codezeilen sind denn relevant? Der Prototyp des Operators und der Kontext indem "find" verwendet wird sollten doch eigentlich ausreichen?

    Welche beiden iteratoren werden denn verwendet? Ich verstehe diese Fehlermeldung schon garnicht. (Ausser hald das meine == Methode nicht der entspricht die der Compiler erwartet)
    Wo liegen die Unterschiede zwischen der (vom Compiler) erwarteten und der von mir gelieferten?



  • Wie gesagt: Liefer zuerst ein aktuelles und fehler-repräsentierendes Codebeispiel, und zwar mit Fehlermeldung und Markierung der fehlerhaften Zeile. Denn beim vorherigen Beispiel wurde das Problem ( a vs. int ) ja schon genannt.

    Und "undefined reference" hat mit operator== nichts zu tun, das ist ein Linkerfehler.

    Übrigens heisst es "voraus".



  • Ok, ich probiers dann nochmal zu präzisieren :

    Hier ein (teil) der Fehler der repräsentativ ist:

    /usr/include/c++/4.4/bits/stl_algo.h: In function ‘_RandomAccessIterator std::__find(_RandomAccessIterator, _RandomAccessIterator, const _Tp&, std::random_access_iterator_tag) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Productionplace**, std::vector<Productionplace*, std::allocator<Productionplace*> > >, _Tp = Productionplace]’:
    /usr/include/c++/4.4/bits/stl_algo.h:4224:   instantiated from ‘_IIter std::find(_IIter, _IIter, const _Tp&) [with _IIter = __gnu_cxx::__normal_iterator<Productionplace**, std::vector<Productionplace*, std::allocator<Productionplace*> > >, _Tp = Productionplace]’
    fraction/Model_Fraction.cpp:34:   instantiated from here
    /usr/include/c++/4.4/bits/stl_algo.h:174: error: no match for ‘operator==’ in ‘__first.__gnu_cxx::__normal_iterator<_Iterator, _Container>::operator* [with _Iterator = Productionplace**, _Container = std::vector<Productionplace*, std::allocator<Productionplace*> >]() == __val’
    fraction/../area/Model_Productionplace.hpp:20: note: candidates are: bool operator==(const Productionplace&, const Productionplace&)
    

    Es werden genannt Model_Fraction.cpp:34 und Model_Productionplace.hpp:20

    hier Model_Fraction.cpp Z.31-37

    void Fraction::rm_prodplace(Productionplace* p) {
    	std::vector<Productionplace*>::iterator begin = prod.begin();
    	std::vector<Productionplace*>::iterator end   = prod.end();
    	std::vector<Productionplace*>::iterator iter = std::find(begin,end,*p); //<- Z.34
    	if(iter != prod.end())
    		prod.erase(iter);
    }
    

    hier Model_Productionplace.hpp Z.20

    inline bool operator==(const Productionplace&,const Productionplace&);
    


  • Ah, ok. Folgendes Problem: Da du in deinem vector Zeiger speicherst, können mit std::find auch nur Zeiger gefunden werden, d.h. es werden nur Zeiger-Vergleiche und keine "Wert"-Vergleiche durchgeführt. Entsprechend musst du auch einen Zeiger übergeben, also "p" und nicht "*p"; das macht dann nur halt was anderes, als du vielleicht willst, es vergleicht ja nur die Identität, nicht Äquivalenz. Oder so.

    Also entweder ist's für dich ok, dass einfach die Zeiger verglichen werden, oder du nimmst std::find_if und übergibst eine vergleichende Funktion welche Zeiger nimmt oder du läufst halt manuell über den Container.



  • danke daran lag es.

    Diese gcc Fehlermeldungen sind ziemlich cryptisch 🙂


Log in to reply