【问题标题】:Using Boost adaptors with C++11 lambdas将 Boost 适配器与 C++11 lambda 配合使用
【发布时间】:2012-08-06 00:54:14
【问题描述】:

我试图编译这段代码:

#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。

这可能是什么问题?有什么办法可以做到这一点?

【问题讨论】:

  • 我认为你需要 1.51。至少这就是它对我有用的原因。

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


【解决方案1】:

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】:

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

        使用 C++17 功能 class template argument deduction,您可以更简单地使用 std::function 进行包装,如下所示:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-09-15
          • 1970-01-01
          • 2012-10-25
          • 2012-09-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-07-24
          相关资源
          最近更新 更多