Kleiner-Operator zum Sortieren überladen



  • Habe es nun mal so als 'freie Funktion' versucht:

    // Operator-Überladung
    const s operator < ( s const& lhs, s const& rhs )
    {
        if ( lhs.wert < rhs.wert ){ return lhs; }
        else { return rhs; }  
    }
    

    Fehler der kommt ist:
    from main.cpp:8:
    /usr/include/c++/4.4/bits/stl_algo.h: In function ‘const _Tp& std::__median(const _Tp&, const _Tp&, const _Tp&) [with _Tp = s]’:
    In file included from /usr/include/c++/4.4/algorithm:62,
    /usr/include/c++/4.4/bits/stl_algo.h:2268: instantiated from ‘void std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator, _Size) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<s*, std::vector<s, std::allocator<s> > >, _Size = int]’
    /usr/include/c++/4.4/bits/stl_algo.h:5220: instantiated from ‘void std::sort(_RAIter, _RAIter) [with _RAIter = __gnu_cxx::__normal_iterator<s*, std::vector<s, std::allocator<s> > >]’
    main.cpp💯 instantiated from here
    /usr/include/c++/4.4/bits/stl_algo.h:89: error: could not convert ‘operator<(const s&, const s&)(((const s&)((const s*)__b)))’ to ‘bool’
    /usr/include/c++/4.4/bits/stl_algo.h:90: error: could not convert ‘operator<(const s&, const s&)(((const s&)((const s*)__c)))’ to ‘bool’
    /usr/include/c++/4.4/bits/stl_algo.h:92: error: could not convert ‘operator<(const s&, const s&)(((const s&)((const s*)__c)))’ to ‘bool’
    /usr/include/c++/4.4/bits/stl_algo.h:96: error: could not convert ‘operator<(const s&, const s&)(((const s&)((const s*)__c)))’ to ‘bool’
    /usr/include/c++/4.4/bits/stl_algo.h:98: error: could not convert ‘operator<(const s&, const s&)(((const s&)((const s*)__c)))’ to ‘bool’
    make[2]: Verlasse Verzeichnis '/home/jay/gtd08042010/begleitend/fu-hagen/masterarbeit/h2r_bioinf/workspace-21122010/spielwiese'
    make[1]: Verlasse Verzeichnis '/home/jay/gtd08042010/begleitend/fu-hagen/masterarbeit/h2r_bioinf/workspace-21122010/spielwiese'
    /usr/include/c++/4.4/bits/stl_algo.h: In function ‘_RandomAccessIterator std::__unguarded_partition(_RandomAccessIterator, _RandomAccessIterator, _Tp) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<s*, std::vector<s, std::allocator<s> > >, _Tp = s]’:
    /usr/include/c++/4.4/bits/stl_algo.h:2268: instantiated from ‘void std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator, _Size) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<s*, std::vector<s, std::allocator<s> > >, _Size = int]’
    /usr/include/c++/4.4/bits/stl_algo.h:5220: instantiated from ‘void std::sort(_RAIter, _RAIter) [with _RAIter = __gnu_cxx::__normal_iterator<s*, std::vector<s, std::allocator<s> > >]’
    main.cpp💯 instantiated from here
    /usr/include/c++/4.4/bits/stl_algo.h:2209: error: could not convert ‘operator<(const s&, const s&)(((const s&)((const s*)(& __pivot))))’ to ‘bool’
    /usr/include/c++/4.4/bits/stl_algo.h:2268: instantiated from ‘void std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator, _Size) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<s*, std::vector<s, std::allocator<s> > >, _Size = int]’
    /usr/include/c++/4.4/bits/stl_algo.h:5220: instantiated from ‘void std::sort(_RAIter, _RAIter) [with _RAIter = __gnu_cxx::__normal_iterator<s*, std::vector<s, std::allocator<s> > >]’
    main.cpp💯 instantiated from here
    /usr/include/c++/4.4/bits/stl_algo.h:2212: error: could not convert ‘operator<(const s&, const s&)(((const s&)((const s*)__last.__gnu_cxx::__normal_iterator<_Iterator, _Container>::operator* [with _Iterator = s*, _Container = std::vector<s, std::allocator<s> >]())))’ to ‘bool’
    /usr/include/c++/4.4/bits/stl_algo.h: In function ‘void std::__insertion_sort(_RandomAccessIterator, _RandomAccessIterator) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<s*, std::vector<s, std::allocator<s> > >]’:
    /usr/include/c++/4.4/bits/stl_algo.h:2178: instantiated from ‘void std::__final_insertion_sort(_RandomAccessIterator, _RandomAccessIterator) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<s*, std::vector<s, std::allocator<s> > >]’
    /usr/include/c++/4.4/bits/stl_algo.h:5222: instantiated from ‘void std::sort(_RAIter, _RAIter) [with _RAIter = __gnu_cxx::__normal_iterator<s*, std::vector<s, std::allocator<s> > >]’
    main.cpp💯 instantiated from here
    /usr/include/c++/4.4/bits/stl_algo.h:2106: error: could not convert ‘operator<(const s&, const s&)(((const s&)((const s*)__first.__gnu_cxx::__normal_iterator<_Iterator, _Container>::operator* [with _Iterator = s*, _Container = std::vector<s, std::allocator<s> >]())))’ to ‘bool’
    /usr/include/c++/4.4/bits/stl_algo.h: In function ‘void std::__heap_select(_RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<s*, std::vector<s, std::allocator<s> > >]’:
    /usr/include/c++/4.4/bits/stl_algo.h:5067: instantiated from ‘void std::partial_sort(_RAIter, _RAIter, _RAIter) [with _RAIter = __gnu_cxx::__normal_iterator<s*, std::vector<s, std::allocator<s> > >]’
    /usr/include/c++/4.4/bits/stl_algo.h:2256: instantiated from ‘void std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator, _Size) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<s*, std::vector<s, std::allocator<s> > >, _Size = int]’
    /usr/include/c++/4.4/bits/stl_algo.h:5220: instantiated from ‘void std::sort(_RAIter, _RAIter) [with _RAIter = __gnu_cxx::__normal_iterator<s*, std::vector<s, std::allocator<s> > >]’
    main.cpp💯 instantiated from here
    /usr/include/c++/4.4/bits/stl_algo.h:1906: error: could not convert ‘operator<(const s&, const s&)(((const s&)((const s*)__first.__gnu_cxx::__normal_iterator<_Iterator, _Container>::operator* [with _Iterator = s*, _Container = std::vector<s, std::allocator<s> >]())))’ to ‘bool’
    /usr/include/c++/4.4/bits/stl_algo.h: In function ‘void std::__unguarded_linear_insert(_RandomAccessIterator, _Tp) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<s*, std::vector<s, std::allocator<s> > >, _Tp = s]’:
    /usr/include/c++/4.4/bits/stl_algo.h:2112: instantiated from ‘void std::__insertion_sort(_RandomAccessIterator, _RandomAccessIterator) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<s*, std::vector<s, std::allocator<s> > >]’
    /usr/include/c++/4.4/bits/stl_algo.h:2178: instantiated from ‘void std::__final_insertion_sort(_RandomAccessIterator, _RandomAccessIterator) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<s*, std::vector<s, std::allocator<s> > >]’
    /usr/include/c++/4.4/bits/stl_algo.h:5222: instantiated from ‘void std::sort(_RAIter, _RAIter) [with _RAIter = __gnu_cxx::__normal_iterator<s*, std::vector<s, std::allocator<s> > >]’
    main.cpp💯 instantiated from here
    /usr/include/c++/4.4/bits/stl_algo.h:2067: error: could not convert ‘operator<(const s&, const s&)(((const s&)((const s*)__next.__gnu_cxx::__normal_iterator<_Iterator, _Container>::operator* [with _Iterator = s*, _Container = std::vector<s, std::allocator<s> >]())))’ to ‘bool’
    from /usr/include/c++/4.4/algorithm:62,
    from main.cpp:8:
    /usr/include/c++/4.4/bits/stl_heap.h: In function ‘void std::__adjust_heap(_RandomAccessIterator, _Distance, _Distance, _Tp) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<s*, std::vector<s, std::allocator<s> > >, _Distance = int, _Tp = s]’:
    In file included from /usr/include/c++/4.4/bits/stl_algo.h:62,
    /usr/include/c++/4.4/bits/stl_heap.h:394: instantiated from ‘void std::make_heap(_RAIter, _RAIter) [with _RAIter = __gnu_cxx::__normal_iterator<s*, std::vector<s, std::allocator<s> > >]’
    /usr/include/c++/4.4/bits/stl_algo.h:1904: instantiated from ‘void std::__heap_select(_RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<s*, std::vector<s, std::allocator<s> > >]’
    /usr/include/c++/4.4/bits/stl_algo.h:5067: instantiated from ‘void std::partial_sort(_RAIter, _RAIter, _RAIter) [with _RAIter = __gnu_cxx::__normal_iterator<s*, std::vector<s, std::allocator<s> > >]’
    /usr/include/c++/4.4/bits/stl_algo.h:2256: instantiated from ‘void std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator, _Size) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<s*, std::vector<s, std::allocator<s> > >, _Size = int]’
    /usr/include/c++/4.4/bits/stl_algo.h:5220: instantiated from ‘void std::sort(_RAIter, _RAIter) [with _RAIter = __gnu_cxx::__normal_iterator<s*, std::vector<s, std::allocator<s> > >]’
    main.cpp💯 instantiated from here
    /usr/include/c++/4.4/bits/stl_heap.h:232: error: could not convert ‘operator<(const s&, const s&)(((const s&)((const s*)__first.__gnu_cxx::__normal_iterator<_Iterator, _Container>::operator+ [with _Iterator = s*, _Container = std::vector<s, std::allocator<s> >](((const ptrdiff_t&)((const ptrdiff_t*)(&(__secondChild + -0x00000000000000001))))).__gnu_cxx::__normal_iterator<_Iterator, _Container>::operator* [with _Iterator = s*, _Container = std::vector<s, std::allocator<s> >]())))’ to ‘bool’
    /usr/include/c++/4.4/bits/stl_heap.h: In function ‘void std::__push_heap(_RandomAccessIterator, _Distance, _Distance, _Tp) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<s*, std::vector<s, std::allocator<s> > >, _Distance = int, _Tp = s]’:
    /usr/include/c++/4.4/bits/stl_heap.h:244: instantiated from ‘void std::__adjust_heap(_RandomAccessIterator, _Distance, _Distance, _Tp) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<s*, std::vector<s, std::allocator<s> > >, _Distance = int, _Tp = s]’
    /usr/include/c++/4.4/bits/stl_heap.h:394: instantiated from ‘void std::make_heap(_RAIter, _RAIter) [with _RAIter = __gnu_cxx::__normal_iterator<s*, std::vector<s, std::allocator<s> > >]’
    /usr/include/c++/4.4/bits/stl_algo.h:1904: instantiated from ‘void std::__heap_select(_RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<s*, std::vector<s, std::allocator<s> > >]’
    /usr/include/c++/4.4/bits/stl_algo.h:5067: instantiated from ‘void std::partial_sort(_RAIter, _RAIter, _RAIter) [with _RAIter = __gnu_cxx::__normal_iterator<s*, std::vector<s, std::allocator<s> > >]’
    /usr/include/c++/4.4/bits/stl_algo.h:2256: instantiated from ‘void std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator, _Size) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<s*, std::vector<s, std::allocator<s> > >, _Size = int]’
    /usr/include/c++/4.4/bits/stl_algo.h:5220: instantiated from ‘void std::sort(_RAIter, _RAIter) [with _RAIter = __gnu_cxx::__normal_iterator<s*, std::vector<s, std::allocator<s> > >]’
    main.cpp💯 instantiated from here
    /usr/include/c++/4.4/bits/stl_heap.h:134: error: no match for ‘operator&&’ in ‘(__holeIndex > __topIndex) && operator<(const s&, const s&)(((const s&)((const s*)(& __value))))’
    /usr/include/c++/4.4/bits/stl_heap.h:134: note: candidates are: operator&&(bool, bool) <built-in>
    make[2]: *** [build/Debug/GNU-Linux-x86/main.o] Fehler 1
    make[1]: *** [.build-conf] Fehler 2
    make: *** [.build-impl] Fehler 2

    BUILD FAILED (exit value 2, total time: 1s)



  • Vielleicht einfach bool zurückgeben?



  • SeppJ meint:

    struct s
    {
        std::string name;
        int  wert;
    };
    // freie Funktion operator<; -> Return Typ ist natürlich bool
    bool operator< ( s const& a, s const& b ) // Bem.: a UND b sind const!
    { 
        return a.wert < b.wert;
    }
    

  • Mod

    Und die andere, technisch richtige, aber ungewöhnliche Methode wäre:

    struct s
    {
        string name;
        int  wert;
    
        bool operator< ( s const& rhs ) const // So macht man Methoden const
        {
            return ( wert < rhs.wert );
        }
    };
    


  • Merci - etz schauen wir mal ob der Build da fluppt!



  • Und const -Lösung:

    bool operator< (s const& rhs) const
    { 
      return this->wert < rhs.wert;
    }
    


  • Jay1980 schrieb:

    Merci - etz schauen wir mal ob der Build da fluppt!

    Und danach lesen wir nochmal die Fehlermeldung und versuchen zu verstehen, was der Compiler uns mitteilen möchte:

    from main.cpp:8:
    /usr/include/c++/4.4/bits/stl_algo.h: In function ‘const _Tp& std::__median(const _Tp&, const _Tp&, const _Tp&) [with _Tp = s]’:
    In file included from /usr/include/c++/4.4/algorithm:62,
    /usr/include/c++/4.4/bits/stl_algo.h:2268: instantiated from ‘void std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator, _Size) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<s*, std::vector<s, std::allocator<s> > >, _Size = int]’
    /usr/include/c++/4.4/bits/stl_algo.h:5220: instantiated from ‘void std::sort(_RAIter, _RAIter) [with _RAIter = __gnu_cxx::__normal_iterator<s*, std::vector<s, std::allocator<s> > >]’
    main.cpp:100: instantiated from here
    /usr/include/c++/4.4/bits/stl_algo.h:89: error: could not convert ‘operator<(const s&, const s&)(((const s&)((const s*)__b)))’ to ‘bool’
    

    Im Grunde genommen ist alles bis zum error: nur ein Wegweiser, wo der Fehler auftaucht, und wo er herkommt. Zeile für Zeile:

    1. (in main.cpp, Zeile 8 hast du etwas geschrieben, was den Fehler verursacht, nämlich incirekt den Header eingebuden, an der die Stelle unmittelbar auftritt)
    2. es wird das Funktionstemplate std::__median instantiiert, mit Templateparameter s. In dieser Funktion passiert der Fehler (Das template befindet sich in stl_algo.h)
    3. (Diese datei wird in <algorithm> auf Zeile 62 includet)
    4. die std::_median-Funktion wird instantiiert, weil std::__introsort_loop instantiiert wurde (Datei- und Zeilenangabe vorne, hinten die angabe welche Templateparameter)
    5. diese Funktion wurde wiederum von std::sort instantiiert (Datei- und Zeilenangabe vorne, hinten die angabe welche Templateparameter)
    6. diese hast du in main.cpp, Zeile 100 instantiiert
    7. Der Fehler (der in std::__median) ist, dass der Compiler das Ergebnis eines operator<(s const&, s const&) nicht in einen bool konvertieren kann.

    Das Einfachste ist immer, nach dem error: zu suchen. Dort steht das eigentliche Problem. Den ganzen Rest bräuchtest du nur, wenn du wissen willst, warum er diesen op< denn überhaupt aufruft und das Ergebnis in ein bool verwandeln möchte.

    Mal was allgemeines zur Operatorüberladung: http://magazin.c-plusplus.net/artikel/�berladung von Operatoren in CPlusPlus (Teil 1)



  • Wunderbar, mein kleines Beispiel läuft, ich strauchle beim Transfer in mein 'richtiges' Programm, bei dem namespaces verwendet werden.

    #include <algorithm>
    #include <cstdlib>
    #include <iostream>
    #include <vector>
    
    using namespace std;
    namespace global {
        struct s {
            string name;
            int wert;
        };
    
    }
    
    // Operator-Überladung als freie Funktion
    bool operator<(global::s const& lhs, global::s const& rhs) {
        return lhs.wert < rhs.wert;
    }
    
    /*
     * 
     */
    int main(int argc, char** argv) {
        cout << " Start Spielwiese ... " << endl;
    
        vector<int> v;
        v.push_back( 2 );
        v.push_back( 3 );
        v.push_back( 1 );
        v.push_back( 5 );
        v.push_back( 6 );
        v.push_back( 4 );
    
        cout << "  Ausgabe der Liste:\n";
        vector<int>::const_iterator iter1 = v.begin();
        int c1 = 0;
        while (iter1 != v.end() )
        {
            cout << "   Lauf ... Item (";
            cout << c1 << "): ";
            cout << *iter1 << ";\n";
            ++iter1;
            c1++;
        }
    
        // Sortierung
        sort( v.begin(), v.end() );
    
        cout << "  Ausgabe der Liste:\n";
        vector<int>::const_iterator iter2 = v.begin();
        int c2 = 0;
        while (iter2 != v.end() )
        {
            cout << "   Lauf ... Item (";
            cout << c2 << "): ";
            cout << *iter2 << ";\n";
            ++iter2;
            c2++;
        }
    
        // Lauf mit Strukturen
        global::s s1;
        s1.name = "Item-Eins";
        s1.wert = 2;
        global::s s2;
        s2.name = "Item-Zwei";
        s2.wert = 3;
        global::s s3;
        s3.name = "Item-Drei";
        s3.wert = 1;
    
        vector<global::s> v2;
        v2.push_back( s1 );
        v2.push_back( s2 );
        v2.push_back( s3 );
    
        cout << "Ausgabe der Listen:\n";
        vector<global::s>::const_iterator iter3 = v2.begin();
        int c3 = 0;
        while (iter3 != v2.end())
        {
            cout << " Lauf ... Item (";
            cout << c3 << "): ";
            cout << iter3->name << " - ";
            cout << iter3->wert << ";\n";
            ++iter3;
            c3++;
        }
    
        // Sortierung
        sort( v2.begin(), v2.end() );
    
        cout << "Ausgabe der Listen:\n";
        vector<global::s>::const_iterator iter4 = v2.begin();
        int c4 = 0;
        while (iter4 != v2.end()) {
            cout << " Lauf ... Item (";
            cout << c4 << "): ";
            cout << iter4->name << " - ";
            cout << iter4->wert << ";\n";
            ++iter4;
            c4++;
        }
    
        cout << " ... ENDE" << endl;
        return 0;
    }
    

    Auszug aus Fehlermeldung, ich habe natürlich genau auf den ersten 'error' geachtet ... mein Überladungsversuch scheint beim Compiler nicht als solcher anzukommen:
    make[1]: Verlasse Verzeichnis '/home/jay/gtd08042010/begleitend/fu-hagen/masterarbeit/h2r_bioinf/workspace-21122010/spielwiese'
    from main.cpp:8:
    /usr/include/c++/4.4/bits/stl_algo.h: In function ‘const _Tp& std::__median(const _Tp&, const _Tp&, const _Tp&) [with _Tp = global::s]’:
    In file included from /usr/include/c++/4.4/algorithm:62,
    /usr/include/c++/4.4/bits/stl_algo.h:2268: instantiated from ‘void std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator, _Size) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<global::s*, std::vector<global::s, std::allocatorglobal::s > >, _Size = int]’
    /usr/include/c++/4.4/bits/stl_algo.h:5220: instantiated from ‘void std::sort(_RAIter, _RAIter) [with _RAIter = __gnu_cxx::__normal_iterator<global::s*, std::vector<global::s, std::allocatorglobal::s > >]’
    main.cpp:98: instantiated from here
    /usr/include/c++/4.4/bits/stl_algo.h:89: error: no match for ‘operator<’ in ‘__a < __b’
    /usr/include/c++/4.4/bits/stl_algo.h:90: error: no match for ‘operator<’ in ‘__b < __c’
    /usr/include/c++/4.4/bits/stl_algo.h:92: error: no match for ‘operator<’ in ‘__a < __c’
    /usr/include/c++/4.4/bits/stl_algo.h:96: error: no match for ‘operator<’ in ‘__a < __c’
    /usr/include/c++/4.4/bits/stl_algo.h:98: error: no match for ‘operator<’ in ‘__b < __c’
    /usr/include/c++/4.4/bits/stl_algo.h: In function ‘_RandomAccessIterator std::__unguarded_partition(_RandomAccessIterator, _RandomAccessIterator, _Tp) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<global::s*, std::vector<global::s, std::allocatorglobal::s > >, _Tp = global::s]’:
    /usr/include/c++/4.4/bits/stl_algo.h:2268: instantiated from ‘void std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator, _Size) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<global::s*, std::vector<global::s, std::allocatorglobal::s > >, _Size = int]’
    /usr/include/c++/4.4/bits/stl_algo.h:5220: instantiated from ‘void std::sort(_RAIter, _RAIter) [with _RAIter = __gnu_cxx::__normal_iterator<global::s*, std::vector<global::s, std::allocatorglobal::s > >]’
    main.cpp:98: instantiated from here



  • Du solltest eventuell den Vergleichsoperator in den Namensraum mit reinpacken:

    namespace global { 
        struct s { 
            string name; 
            int wert; 
        }; 
        bool operator<(s const& lhs, s const& rhs) { 
            return lhs.wert < rhs.wert; 
        } 
    
    }
    

    (keine Sorge - der Compiler ist clever genug, den Operator dort zu finden)


  • Mod

    Wenn du das wie CStoll empfiehlt machst, dann kannst du auch noch mal nach "argument dependent lookup" oder "Koenig lookup" googlen. Das ist zwar eine recht spezielle Eigenschaft von C++, aber wichtig zu wissen, wenn man mit Namespaces arbeitet.


  • Mod

    CStoll schrieb:

    Du solltest eventuell den Vergleichsoperator in den Namensraum mit reinpacken:

    Nicht nur eventuell. Da Überladungen für < auch im Namensraum std existieren, wird beim unqualifizierten Lookup innerhalb eines Standardalgorithmus der globale Namensraum wahrscheinlich nicht durchsucht werden. Damit bleibt nur ADNL übrig.


Anmelden zum Antworten