2012-08-08 12 views
17

tôi đã cố gắng để biên dịch mã này:Sử dụng adapter Boost với 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; 
} 

Việc lập thất bại với các thông báo lỗi sau (sau khi một cuốn tiểu thuyết instantiation mẫu dài):

/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 

Tôi đã giải quyết vấn đề và tìm thấy this trong lưu trữ danh sách gửi thư của Người dùng nâng cao. Nó gợi ý rằng việc sử dụng #define BOOST_RESULT_OF_USE_DECLTYPE sẽ giải quyết được vấn đề. Tôi đặt nó vào đầu mã của tôi, nhưng nó vẫn không biên dịch. Độ dài của thông báo lỗi có vẻ ngắn hơn nhiều, nhưng thông báo lỗi ở cuối là như nhau. Tôi hiện đang sử dụng Boost 1.50.

Điều gì có thể là vấn đề ở đây? Có cách nào để thực hiện công việc này không?

+0

Tôi nghĩ bạn cần 1.51. Ít nhất đó là những gì làm cho nó làm việc cho tôi. – Gurgeh

Trả lời

8

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

Nhưng bạn có thể sử dụng tính năng này hoạt động tốt.

#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 hoạt động tốt trong VS2012 ví dụ.

6

Điều này được bao phủ tại http://boost.2283326.n4.nabble.com/range-cannot-use-lambda-predicate-in-adaptor-with-certain-algorithms-td3560157.htmlhttps://svn.boost.org/trac/boost/ticket/4189 - vấn đề là một số thuật toán hy vọng có thể sao chép (và mặc định xây dựng và sao chép gán) vị từ của chúng, không thể được thực hiện với lambda.

Cách giải quyết là để quấn lambda trong một std::function:

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

Tôi đã yêu cầu (tại Inferring the call signature of a lambda or arbitrary callable for "make_function") cho một cách để viết một make_function như vậy mà người ta chỉ có thể viết:

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

Bạn có thể biến lambda không bắt được thành con trỏ hàm bằng cách đặt dấu "+" ở phía trước nó.

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

điều này làm việc cho tôi! –