2011-02-25 20 views
74
sort(mMyClassVector.begin(), mMyClassVector.end(), 
    [](const MyClass & a, const MyClass & b) 
{ 
    return a.mProperty > b.mProperty; 
}); 

Me gustaría utilizar 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:¿Cómo ordenar con un lambda?

error C2564: 'const char *' : a function-style conversion to a built-in type can only take one argument

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

+0

¿Qué tipo es el 'vector <>'? – JaredPar

+0

¿Qué tipo es 'mProperty'? – wilhelmtell

+0

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

Respuesta

80

Lo tengo.

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

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

+28

¡Qué 'operador> travieso', entonces. – GManNickG

+2

Lo que has escrito hasta ahora tiene poco sentido. Si mProperty se supone que es una int 'a.mProperty> b.mProperty' definitivamente generará un bool. – sellibitze

+0

Entonces entiendes mi confusión. Creo que podría ser algo raro con mi VC10 Express (sin Service Pack). Trasladé el proyecto a una máquina con Visual Studio 2010 Team y funcionó sin el "-> bool". – BTR

3

¿Puede ser el problema con la línea "a.mProperty> b.mProperty"? He recibido el código siguiente a la obra:

#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 salida 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, 
+0

Sí, algo complicado con la configuración en la que estaba. Compilando en mi computadora portátil sin hacerlo bien en la edición Team de Visual Studio 2010. Lo que me dio la pista fue en qué había cambiado para enlazar y el error no desaparecería. Estaba en VC10 Express. ¿Error? – BTR

+0

No tengo idea; El código que publiqué compiló y funcionó bien con g ++. – Stephan

3

Para tanto código, se puede utilizar de esta manera:

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

Sustituir "vec" con tu clase y eso es todo.

+0

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

+0

Lo siento, no sé cómo me lo perdí. Mis ojos se detienen en la publicación de Stephan. Mi mal. (Modifico la publicación después de tus sugerencias) – John