简体   繁体   English

使用带有C ++ 11 lambdas的Boost适配器

[英]Using Boost adaptors with C++11 lambdas

I tried to compile this code: 我试着编译这段代码:

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

The compilation failed with the following error message (after a long template instantiation novel): 编译失败,出现以下错误消息(在长模板实例化小说之后):

/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

I googled the problem, and found this in the Boost Users mailing list archive. 我搜索了问题,并在Boost Users邮件列表存档中找到了这个问题。 It suggested that using #define BOOST_RESULT_OF_USE_DECLTYPE would solve the problem. 它建议使用#define BOOST_RESULT_OF_USE_DECLTYPE来解决问题。 I put it into the very beginning of my code, but it still doesn't compile. 我把它放在我的代码的最开头,但它仍然没有编译。 The length of the error message seems to be much shorter, but the error message at the end is the same. 错误消息的长度似乎要短得多,但最后的错误消息是相同的。 I'm currently using Boost 1.50. 我目前正在使用Boost 1.50。

What can be the problem here? 这可能是什么问题? Is there any way to make this work? 有没有办法让这项工作?

You can turn a non-capturing lambda into a function pointer by putting a "+" in front of it. 您可以通过在其前面放置一个“+”将非捕获lambda转换为函数指针。

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/ http://smellegantcode.wordpress.com/2011/10/31/linq-to-c-or-something-much-better/

But you can use this, that works well. 但你可以使用它,这很好用。

#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 http://liveworkspace.org/code/b78b3f7d05049515ac207e0c12054c70

#define BOOST_RESULT_OF_USE_DECLTYPE works fine in VS2012 for example. #define BOOST_RESULT_OF_USE_DECLTYPE在VS2012中工作正常。

This is covered at http://boost.2283326.n4.nabble.com/range-cannot-use-lambda-predicate-in-adaptor-with-certain-algorithms-td3560157.html and https://svn.boost.org/trac/boost/ticket/4189 - the problem is that some algorithms expect to be able to copy-construct (and default-construct, and copy-assign) their predicate, which can't be done with a lambda. 这可以在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 - 问题是某些算法希望能够复制构造(以及默认构造和复制分配)它们的谓词,这不能用lambda完成。

The workaround is to wrap the lambda in a std::function : 解决方法是将lambda包装在std::function

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

I've asked (at Inferring the call signature of a lambda or arbitrary callable for "make_function" ) for a way to write a make_function such that one can just write: 我已经问过(在推断lambda的调用签名或“make_function”的任意调用时 ),以便编写一个make_function ,以便人们可以写:

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

With C++17 feature class template argument deduction you can wrap with std::function simplier, like this: 使用C ++ 17要素类模板参数推导,您可以用std :: function简化包装,如下所示:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM