2012-08-08 12 views
17

Próbowałem skompilować ten kod:Korzystanie adaptery Podbijanie przy C++ 11 lambdas

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

Kompilacja nie powiodła się z następującym komunikatem o błędzie (po długim szablonu konkretyzacji powieści):

/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 

Przeanalizowałem ten problem i znalazłem this w archiwum listy adresowej dla użytkowników boost. Sugerował on, że rozwiązanie problemu może rozwiązać za pomocą metody #define BOOST_RESULT_OF_USE_DECLTYPE. Umieściłem go na samym początku mojego kodu, ale nadal się nie kompiluje. Długość komunikatu o błędzie wydaje się być znacznie krótsza, ale komunikat o błędzie na końcu jest taki sam. Obecnie używam Boost 1.50.

Co może stanowić problem? Czy jest jakiś sposób, aby to zadziałało?

+0

Myślę, że potrzebujesz 1,51. Przynajmniej to właśnie sprawiło, że zadziałało to dla mnie. – Gurgeh

Odpowiedz

8

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

Ale można użyć tego, że działa dobrze.

#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 działa dobrze w VS2012 na przykład.

6

To jest pokryta w http://boost.2283326.n4.nabble.com/range-cannot-use-lambda-predicate-in-adaptor-with-certain-algorithms-td3560157.html i https://svn.boost.org/trac/boost/ticket/4189 - problemem jest to, że niektóre algorytmy oczekiwać, aby być w stanie skopiować-konstrukt (i domyślną-Construct, i kopia assign) swoje orzeczenie, które nie mogą być wykonane z lambda.

Rozwiązaniem jest owinąć lambda w std::function:

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

Poprosiłem (w Inferring the call signature of a lambda or arbitrary callable for "make_function") sposobu, aby napisać make_function taki, że można po prostu napisać:

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

Możesz przekształcić niezapisującą lambdę w wskaźnik funkcji, umieszczając przed nią znak "+".

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; 
+0

to działało dla mnie! –