2012-01-05 19 views
19

que estoy tratando de implementar un mapa con una función lambda en C++ 11 como talLambdas en Mapas

std::map<int, int, [](const int&a, const int& b) { return a < b; }> test; 

pero que falla con

error: type/value mismatch at argument 3 in template parameter list for ‘template<class _Key, class _Tp, class _Compare, class _Alloc> class std::map’

error: expected a type, got ‘{}’

error: invalid type in declaration before ‘;’ token

algún consejo?

+1

Has proporcionado una lambda, es decir, un objeto; el parámetro de la plantilla debe ser _type_, no una instancia de un tipo. – ildjarn

+0

Consulte [C++ priority_queue with lambda comparator error] (http://stackoverflow.com/questions/5807735/c-priority-queue-with-lambda-comparator-error) y [¿Puede el 'tipo' de una expresión lambda ser ¿expresado?] (http://stackoverflow.com/questions/3867276/can-the-type-of-a-lambda-expression-be-expressed). –

Respuesta

25

Debe pasar el tipo de lambda como argumento de plantilla, no la lambda en sí. Lo que se quiere es la siguiente:

auto mycomp = [](const int&a, const int& b) { return a < b; }; 
std::map<int, int, decltype(mycomp)> test(mycomp); 

Aunque, de hecho, ya que su lambda tiene ninguna captura, sino que puede ser almacenada en un puntero de función, por lo que, alternativamente, se puede hacer esto:

std::map<int, int, bool(*)(const int&,const int&)> 
    test([](const int&a, const int& b) { return a < b; }); 

Aunque Encuentro el primero mucho más legible. Aunque usar el tipo de puntero de función es más versátil. es decir, puede aceptar cualquier puntero de función o lambda no capturable que coincida con esa firma. Pero si cambias tu lambda para capturar, no funcionará. Para una versión más versátil, se puede utilizar std::function, es decir:

std::map<int, int, std::function<bool(const int&, const int&)>> 

que funcionará con cualquier función, lambda (captura o no) o la función de objeto, siempre y cuando coincida con la firma.

+0

Muy bien, Sr. Lindley. –

+0

Tenga en cuenta que si se declararan 2 mapas, tendrían 2 tipos diferentes y serían incompatibles. –

+0

@Jesse: Ese sería un argumento para usar un tipo de puntero a función en lugar de decltype en el lambda, como hice en mi segundo ejemplo. Pero mejor (para la compatibilidad, no la eficiencia) sería utilizar una 'std :: function', entonces sería compatible incluso con lambdas que captura y otros objetos de función. –