¿Cómo ordenar con una lambda?


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

Me gustaría usar una función lambda para ordenar clases personalizadas en lugar de vincular un método de instancia. Sin embargo, el código anterior produce el error:

error C2564: 'const char *': una conversión de estilo de función a un tipo incorporado solo puede tomar un argumento

Funciona bien con boost::bind(&MyApp::myMethod, this, _1, _2).


El vector es de una estructura que contiene un número entero y dos cadenas. La propiedad aquí sería un número entero.
BTR

44
Muéstranos un pequeño ejemplo compilable .
GManNickG

Respuestas:


157

Entendido.

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

Supuse que descubriría que el operador> devolvió un bool (por documentación). Pero aparentemente no es así.


39
Qué mierda operator>, entonces.
GManNickG

2
Lo que has escrito hasta ahora tiene poco sentido. Si se supone que mProperty es un int a.mProperty>b.mPropertydefinitivamente producirá un bool.
sellibitze

1
Entonces entiendes mi confusión. Creo que podría ser algo extraño con mi VC10 Express (sin paquete de servicio). Moví el proyecto a una máquina con Visual Studio 2010 Team y funcionó sin el "-> bool".
BTR

8
¿No debería ser operator<así operator>?
Warpspace

8
Sí, debería ser <, para el orden ascendente estándar. ¡Edité la respuesta para dejar en claro que era un tipo descendente, pero aparentemente mi edición no fue útil y se borró!
panqueque

18

Para mucho código, puede usarlo así:

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

Reemplace "vec" con su clase y eso es todo.


¿Cómo es tu respuesta diferente a BTR? Por cierto. puede usar std :: begin (vec) y std :: end (vec) para hacerlo más c ++ 11.
Logman

Lo siento, no sé cómo me perdí eso. Mis ojos se detienen en el puesto de Stephan. Mi mal. (Modifico la publicación después de sus sugerencias)
Adrian

5

¿Puede ser el problema con la línea "a.mProperty> b.mProperty"? Tengo el siguiente código para trabajar:

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

El resultado es:

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

Sí, algo complicado con la configuración en la que estaba. Compilar en mi computadora portátil sin ella está bien en la edición Team de Visual Studio 2010. Lo que me dio pistas sobre lo que había cambiado para vincular y el error no desaparecería. Estaba en VC10 Express. ¿Insecto?
BTR
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.