Comment trier avec un lambda?


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

Je voudrais utiliser une fonction lambda pour trier les classes personnalisées au lieu de lier une méthode d'instance. Cependant, le code ci-dessus génère l'erreur:

erreur C2564: 'const char *': une conversion de style fonction en type intégré ne peut prendre qu'un seul argument

Cela fonctionne bien avec boost::bind(&MyApp::myMethod, this, _1, _2).


Le vecteur est d'une structure qui contient un entier et deux chaînes. La propriété ici serait un entier.
BTR

4
Montrez-nous un petit exemple compilable .
GManNickG

Réponses:


159

Je l'ai.

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

J'ai supposé qu'il comprendrait que l'opérateur> retournait un booléen (par documentation). Mais apparemment ce n'est pas le cas.


39
Quelle merde operator>, alors.
GManNickG

2
Ce que vous avez écrit jusqu'à présent n'a guère de sens. Si mProperty est supposé être un int, il a.mProperty>b.mPropertyproduira définitivement un booléen.
sellibitze

1
Alors vous comprenez ma confusion. Je pense que cela pourrait être quelque chose de bizarre avec mon VC10 Express (pas de service pack). J'ai déplacé le projet sur une machine avec Visual Studio 2010 Team et cela a fonctionné sans le "-> bool".
BTR

8
Ne devrait-il pas l'être operator<, non operator>?
Warpspace du

8
Oui, cela devrait être <, pour l'ordre croissant standard. J'ai édité la réponse pour qu'il soit clair que c'était un tri décroissant mais apparemment ma modification n'a pas été utile et a été effacée!
pancake

19

Trop de code, vous pouvez l'utiliser comme ceci:

#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;
}

Remplacez "vec" par votre classe et c'est tout.


En quoi votre réponse est-elle différente de BTR? Btw. vous pouvez utiliser std :: begin (vec) et std :: end (vec) pour le rendre plus c ++ 11.
Logman

Désolé, je ne sais pas comment j'ai raté ça. Mes yeux s'arrêtent au poste de Stephan. Mon mauvais. (Je modifie le message après vos suggestions)
Adrian

5

Le problème peut-il provenir de la ligne "a.mProperty> b.mProperty"? J'ai obtenu le code suivant pour fonctionner:

#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;
};

La sortie est:

before sort: 83, 86, 77, 15, 93, 35, 86, 92, 49, 21,
after sort:  93, 92, 86, 86, 83, 77, 49, 35, 21, 15,

Ouais, quelque chose de louche avec la configuration sur laquelle j'étais. Compiler sur mon ordinateur portable sans cela très bien sur l'édition Team de Visual Studio 2010. Ce qui m'a indiqué dans ce que je suis retourné pour lier et l'erreur ne disparaîtrait pas. J'étais sur VC10 Express. Punaise?
BTR
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.