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

时间:2012-08-08 20:22:46

标签: c++ boost lambda c++11 boost-range

我尝试编译此代码:

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

编译失败,出现以下错误消息(在长模板实例化小说之后):

/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

我搜索了问题,并在Boost Users邮件列表存档中找到了this。它建议使用#define BOOST_RESULT_OF_USE_DECLTYPE来解决问题。我把它放在我的代码的最开头,但它仍然没有编译。错误消息的长度似乎要短得多,但最后的错误消息是相同的。我目前正在使用Boost 1.50。

这可能是什么问题?有没有办法让这项工作?

4 个答案:

答案 0 :(得分:9)

您可以通过在其前面加上“+”将非捕获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;

答案 1 :(得分:8)

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

但你可以使用它,效果很好。

#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在VS2012中运行良好。

答案 2 :(得分:6)

这涵盖在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完成。

解决方法是将lambda包装在std::function

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

我已经(Inferring the call signature of a lambda or arbitrary callable for "make_function")询问了一种写make_function的方法,以便人们可以写:

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

答案 3 :(得分:0)

借助C ++ 17功能class template argument deduction,您可以使用std :: function简化包装,如下所示:

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