Wie sortiere ich mit einem Lambda?

135
sort(mMyClassVector.begin(), mMyClassVector.end(), 
    [](const MyClass & a, const MyClass & b)
{ 
    return a.mProperty > b.mProperty; 
});

Ich möchte eine Lambda-Funktion verwenden, um benutzerdefinierte Klassen zu sortieren, anstatt eine Instanzmethode zu binden. Der obige Code liefert jedoch den Fehler:

Fehler C2564: 'const char *': Eine Konvertierung im Funktionsstil in einen integrierten Typ kann nur ein Argument annehmen

Es funktioniert gut mit boost::bind(&MyApp::myMethod, this, _1, _2).

BTR
quelle
Der Vektor besteht aus einer Struktur, die eine Ganzzahl und zwei Zeichenfolgen enthält. Die Eigenschaft hier wäre eine ganze Zahl.
BTR
4
Zeigen Sie uns ein kleines kompilierbares Beispiel.
GManNickG

Antworten:

155

Verstanden.

sort(mMyClassVector.begin(), mMyClassVector.end(), 
    [](const MyClass & a, const MyClass & b) -> bool
{ 
    return a.mProperty > b.mProperty; 
});

Ich nahm an, es würde sich herausstellen, dass der Operator> einen Bool zurückgegeben hat (gemäß Dokumentation). Aber anscheinend ist es nicht so.

BTR
quelle
38
Was für ein Mist operator>dann.
GManNickG
2
Was Sie bisher geschrieben haben, macht wenig Sinn. Wenn mProperty ein int a.mProperty>b.mPropertysein soll, ergibt sich definitiv ein Bool.
Sellibitze
1
Dann verstehst du meine Verwirrung. Ich denke, es könnte etwas Seltsames mit meinem VC10 Express sein (kein Service Pack). Ich habe das Projekt mit Visual Studio 2010 Team auf einen Computer verschoben und es funktionierte ohne "-> bool".
BTR
8
Sollte es nicht sein operator<, nicht operator>?
Warpspace
8
Ja <, bei aufsteigender Standardreihenfolge. Ich habe die Antwort bearbeitet, um zu verdeutlichen, dass es sich um eine absteigende Sorte handelt, aber anscheinend war meine Bearbeitung nicht hilfreich und wurde gelöscht!
Pfannkuchen
18

Zu viel Code können Sie folgendermaßen verwenden:

#include<array>
#include<functional>

int main()
{
    std::array<int, 10> vec = { 1,2,3,4,5,6,7,8,9 };

    std::sort(std::begin(vec), 
              std::end(vec), 
              [](int a, int b) {return a > b; });

    for (auto item : vec)
      std::cout << item << " ";

    return 0;
}

Ersetzen Sie "vec" durch Ihre Klasse und das wars.

Adrian
quelle
Wie unterscheidet sich Ihre Antwort von BTR? Übrigens. Sie können std :: begin (vec) und std :: end (vec) verwenden, um es c ++ 11 zu machen.
Logman
Entschuldigung, ich weiß nicht, wie ich das verpasst habe. Meine Augen bleiben bei Stephan stehen. Mein schlechtes. (Ich ändere den Beitrag nach Ihren Vorschlägen)
Adrian
5

Kann das Problem bei der Zeile "a.mProperty> b.mProperty" liegen? Ich habe den folgenden Code zum Laufen gebracht:

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

struct Foo
{
    Foo() : _i(0) {};

    int _i;

    friend std::ostream& operator<<(std::ostream& os, const Foo& f)
    {
        os << f._i;
        return os;
    };
};

typedef std::vector<Foo> VectorT;

std::string toString(const VectorT& v)
{
    std::stringstream ss;
    std::copy(v.begin(), v.end(), std::ostream_iterator<Foo>(ss, ", "));
    return ss.str();
};

int main()
{

    VectorT v(10);
    std::for_each(v.begin(), v.end(),
            [](Foo& f)
            {
                f._i = rand() % 100;
            });

    std::cout << "before sort: " << toString(v) << "\n";

    sort(v.begin(), v.end(),
            [](const Foo& a, const Foo& b)
            {
                return a._i > b._i;
            });

    std::cout << "after sort:  " << toString(v) << "\n";
    return 1;
};

Die Ausgabe ist:

before sort: 83, 86, 77, 15, 93, 35, 86, 92, 49, 21,
after sort:  93, 92, 86, 86, 83, 77, 49, 35, 21, 15,
Stephan
quelle
Ja, etwas Verrücktes mit dem Setup, auf dem ich war. Das Kompilieren auf meinem Laptop ohne es ist in der Team Edition von Visual Studio 2010 in Ordnung. Was hat mich daran erinnert, was ich zum Binden zurückgeschaltet habe und der Fehler würde nicht verschwinden. Ich war auf VC10 Express. Fehler?
BTR