c++ boost lambda c++11 boost-range

Uso de adaptadores Boost con C++ 11 lambdas



c++11 boost-range (3)

Traté de compilar este código:

#include <boost/range/adaptors.hpp> #include <boost/range/algorithm.hpp> #include <vector> int main() { std::vector<int> v{ 1,5,4,2,8,5,3,7,9 }; std::cout << *boost::min_element(v | boost::adaptors::transformed( [](int i) { return -i; })) << std::endl; return 0; }

La compilación falló con el siguiente mensaje de error (después de una nueva instancia de plantilla larga):

/usr/local/include/boost/iterator/transform_iterator.hpp:84:26: error: use of deleted function ‘main()::<lambda(int)>::<lambda>()’ ../main.cpp:12:5: error: a lambda closure type has a deleted default constructor

Busqué en Google el problema y lo encontré en el archivo de la lista de correo de los usuarios de Boost. Sugirió que usar #define BOOST_RESULT_OF_USE_DECLTYPE resolvería el problema. Lo puse al principio de mi código, pero todavía no compila. La longitud del mensaje de error parece ser mucho más corta, pero el mensaje de error al final es el mismo. Actualmente estoy usando Boost 1.50.

¿Cuál puede ser el problema aquí? ¿Hay alguna manera de hacer funcionar esto?


Esto está cubierto en http://boost.2283326.n4.nabble.com/range-cannot-use-lambda-predicate-in-adaptor-with-certain-algorithms-td3560157.html y https: //svn.boost. org / trac / boost / ticket / 4189 - el problema es que algunos algoritmos esperan poder copiar-construir (y construir por defecto, y copiar-asignar) su predicado, lo que no se puede hacer con un lambda.

La solución consiste en ajustar el lambda en una std::function

*boost::min_element( v | boost::adaptors::transformed(std::function<int(int)>( [](int i) { return -i; })));

He pedido (en Inferring the call signature of a lambda o arbitrary invocable para "make_function" ) una forma de escribir make_function modo que solo se pueda escribir:

*boost::min_element( v | boost::adaptors::transformed(make_function( [](int i) { return -i; })));


Puede convertir un lambda que no captura en un puntero de función colocando un "+" delante de él.

std::vector<int> v{1,5,4,2,8,5,3,7,9}; std::cout << *boost::min_element(v | boost::adaptors::transformed(+[](int i) { return -i; })) << std::endl;


http://smellegantcode.wordpress.com/2011/10/31/linq-to-c-or-something-much-better/

Pero puedes usar esto, eso funciona bien.

#include <boost/range/adaptors.hpp> #include <boost/range/algorithm.hpp> #include <vector> #include <functional> int main() { std::vector<int> v{ 1,5,4,2,8,5,3,7,9 }; std::function<int(int)> func = [](int i) { return -i; }; std::cout << *boost::min_element(v | boost::adaptors::transformed( func)) << std::endl; return 0; }

http://liveworkspace.org/code/b78b3f7d05049515ac207e0c12054c70

#define BOOST_RESULT_OF_USE_DECLTYPE funciona bien en VS2012, por ejemplo.