c++: algorithm sort: Problem mit g++

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
badera
Beiträge: 643
Registriert: 20.05.2004 20:01:50
Wohnort: Schweiz

c++: algorithm sort: Problem mit g++

Beitrag von badera » 07.04.2007 15:47:11

Folgendes Code-Minimalbeispiel:

Die Zeile sort (mRows.begin(), mRows.end(), cmp_cdhsrow); verursacht die vielen Fehler!.

Code: Alles auswählen

#include <vector>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <sstream>

using namespace std;

class CDHSRow
{
    protected:
        vector<string>      mFields;
        vector<int>         mLens;
        vector<int>         mIdx;

    public:
        void addField (int idx, const char *data, int size);

        bool operator< (const CDHSRow &a)
            { return mFields[0] < a.mFields[0]; }

        bool operator== (const CDHSRow &a)
            { return mFields[0] == a.mFields[0]; }

};

void CDHSRow::addField (int idx, const char *data, int size)
{
    string  field (data, size);
    mFields.push_back(field);
    mLens.push_back(size);
    mIdx.push_back(idx);
}


bool cmp_cdhsrow (CDHSRow &a, CDHSRow &b)
{
    return a < b;
}

int main(int, char **)
{
    vector<CDHSRow>         mRows;

    // einige Zeilen mRows einfügen... anschliessend sortieren

    sort (mRows.begin(), mRows.end(), cmp_cdhsrow);

    return 0;
}
Ergibt mit KDevelop (g++) folgende Fehler aus:

Code: Alles auswählen

cd '.../testsort/debug' && WANT_AUTOCONF_2_5="1" WANT_AUTOMAKE_1_6="1" make -k 
make all-recursive
Making all in src
compiling testsort.cpp (g++)
/usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../include/c++/4.1.2/bits/stl_algo.h: In function ‘const _Tp& std::__median(const _Tp&, const _Tp&, const _Tp&, _Compare) [with _Tp = CDHSRow, _Compare = bool (*)(CDHSRow&, CDHSRow&)]’:
/usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../include/c++/4.1.2/bits/stl_algo.h:2679: instantiated from ‘void std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator, _Size, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<CDHSRow*, std::vector<CDHSRow, std::allocator<CDHSRow> > >, _Size = int, _Compare = bool (*)(CDHSRow&, CDHSRow&)]’
/usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../include/c++/4.1.2/bits/stl_algo.h:2749: instantiated from ‘void std::sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<CDHSRow*, std::vector<CDHSRow, std::allocator<CDHSRow> > >, _Compare = bool (*)(CDHSRow&, CDHSRow&)]’
.../testsort/src/testsort.cpp:45: instantiated from here
/usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../include/c++/4.1.2/bits/stl_algo.h:125: error: invalid initialization of reference of type ‘CDHSRow&’ from expression of type ‘const CDHSRow’
/usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../include/c++/4.1.2/bits/stl_algo.h:126: error: invalid initialization of reference of type ‘CDHSRow&’ from expression of type ‘const CDHSRow’
/usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../include/c++/4.1.2/bits/stl_algo.h:128: error: invalid initialization of reference of type ‘CDHSRow&’ from expression of type ‘const CDHSRow’
/usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../include/c++/4.1.2/bits/stl_algo.h:132: error: invalid initialization of reference of type ‘CDHSRow&’ from expression of type ‘const CDHSRow’
/usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../include/c++/4.1.2/bits/stl_algo.h:134: error: invalid initialization of reference of type ‘CDHSRow&’ from expression of type ‘const CDHSRow’
make[2]: *** [testsort.o] Error 1
make[2]: Target `all' not remade because of errors.
make[1]: *** [all-recursive] Error 1
make: *** [all] Error 2
*** Exited with status: 2 ***
Was mach ich falsch? - Mit Borland C++ Builder 6.0 kann ich das kompilieren, mit KDevelop 3.3.5 mit g++ 4.1.2 nicht. Irgendwie ist es wieder sowas, wie im Thread vorhin: http://www.debianforum.de/forum/viewtopic.php?t=82089

Kann mir wieder jemand weiterhelfen? - Besten Dank schon im Voraus!
- Adrian

Benutzeravatar
uljanow
Beiträge: 529
Registriert: 20.09.2005 21:14:00

Beitrag von uljanow » 07.04.2007 15:57:52

Code: Alles auswählen

-bool cmp_cdhsrow (CDHSRow &a, CDHSRow &b)
+bool cmp_cdhsrow (CDHSRow a, CDHSRow b)  
wird ja fast zum quiz hier. :)

Benutzeravatar
badera
Beiträge: 643
Registriert: 20.05.2004 20:01:50
Wohnort: Schweiz

Beitrag von badera » 07.04.2007 16:12:04

Hmm, ich bin etwas sprachlos! 8O - vielen Dank!

Warum denn?? Und überhaupt: Warum braucht es überhaupt eine compare-Funktion hier bei sort? - Schliesslich hat ja CDHSRow den < operator einprogrammiert. Schon das begreife ich nicht ganz.

g++ scheint massiv ekliger und genauer zu sein, als Borland C++ Builder - ist ja auch gut so. Nur ists ziemlich schwierig, von einem toleranteren Compiler auf so einen strikten Code zu portieren...

Danke jedenfalls - uljanow - für Deine starke Hilfe!
- Adrian

Benutzeravatar
armin
Beiträge: 2682
Registriert: 17.03.2005 11:49:14

Beitrag von armin » 07.04.2007 16:26:58

badera hat geschrieben:g++ scheint massiv ekliger und genauer zu sein, als Borland C++ Builder - ist ja auch gut so. Nur ists ziemlich schwierig, von einem toleranteren Compiler auf so einen strikten Code zu portieren...
Hihi, das kenne ich.
Ich bin gerade dabei Code der unter Visual Studio 2005 problemlos läuft mit dem GCC zum laufen zu bringen. Ein ähnliches Problem wie Obiges ist mir dabei auch schon über den Weg gelaufen (neben diversen anderen) ;)
Formerly known as Trigger.
HP 8510p - Debian Sid
Mitglied des Debian-KDE-Teams

gms
Beiträge: 7798
Registriert: 26.11.2004 20:08:38
Lizenz eigener Beiträge: MIT Lizenz

Beitrag von gms » 07.04.2007 16:50:21

badera hat geschrieben:Warum denn?? Und überhaupt: Warum braucht es überhaupt eine compare-Funktion hier bei sort? - Schliesslich hat ja CDHSRow den < operator einprogrammiert. Schon das begreife ich nicht ganz.
du brauchst keine compare Funktion wenn der < operator richtig ( als const ) deklariert wurde:

Code: Alles auswählen

        bool operator< (const CDHSRow &a) const
            { return mFields[0] < a.mFields[0]; } 
Gruß
gms

Edit: Das ist übrigens auch die Variante die preferiert werden sollte! Bei der Varianter mit der Compare Funktion werden Kopien der Objekte angelegt und diese dann verglichen. Das Vergleich über kopierte Elemente ist auch sinnvoll, wenn davon ausgegangen werden kann, daß es keinen < operator gibt, der die Objekte nicht verändert, also wenn der < operator nicht als const deklariert wurde.

Antworten