Problem bei std::sort mit Funktor



  • Hi,
    ich habe für das Problem mal ein Minimalbeispiel gemacht. Mein Funktor besitzt als Member einen std::vector . Merkwürdig ist nun, dass der std::vector zurückgesetzt wird, wenn std::sort den operator() aufruft und der Vergleich lhs<rhs false ergibt. Habe es schon gedebugged, konnte aber nicht feststellen, wann (und vor allem) weshalb das passiert. Kann jemand von euch das Verhalten erklären?

    #include <iostream>
    #include <vector>
    #include <algorithm>
    using namespace std;
    
    struct compare
    {
    	vector<unsigned> vec;
    
    	compare()
    	{
    		for(unsigned i=0; i!=10; ++i)
    			vec.push_back( 8 );
    	}
    
        bool operator()(int lhs, int rhs)
        {
    		cout << vec[0] << '\n';
    		vec[0] = 123;
    		return lhs < rhs;
    	}
    };
    
    int main()
    {
    	int ar[] = {9,8,7,6,5};
    	std::sort( ar, ar+5, compare() );
    }
    

    Die Ausgabe ist:
    `

    8

    123

    8

    123

    8

    123

    8

    123

    `

    Danke im Voraus.



  • std::sort kopiert das Objekt mehrmals. GIb noch die Addresse des objektes aus, dann wird es klarer.


  • Mod

    Algorithmen dürfen im Allgemeinen Funktoren, die sie als Argumente erhalten frei kopieren. Es ist also nicht bestimmt, dass immer das gleiche Funktionsobjekt für alle Vergleiche benutzt wird.
    Ein reference_wrapper sollte hier helfen.

    compare comp;
    std::sort( ar, ar+5, std::ref(comp) );
    


  • camper schrieb:

    Algorithmen dürfen im Allgemeinen Funktoren, die sie als Argumente erhalten frei kopieren. Es ist also nicht bestimmt, dass immer das gleiche Funktionsobjekt für alle Vergleiche benutzt wird.

    Ah ok, danke das wusste ich nicht. Hab eben einen Copy-Ctor hinzugefügt, und du hast Recht, es wird häufig kopiert. Wieder was gelernt... erst dachte ich, ich muss dem VC11 die Schuld geben :p.

    camper schrieb:

    Ein reference_wrapper sollte hier helfen.

    compare comp;
    std::sort( ar, ar+5, std::ref(comp) );
    

    Jup, funktioniert, danke. 🙂


Anmelden zum Antworten