我试图编译这段代码:
#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邮件列表存档中找到了这个问题。它建议使用#define BOOST_RESULT_OF_USE_DECLTYPE
可以解决问题。我把它放在代码的最开头,但它仍然无法编译。错误消息的长度似乎要短得多,但末尾的错误消息是相同的。我目前正在使用Boost 1.50。
这里可能有什么问题?有什么办法可以做到这一点吗?
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中工作正常。
非捕获 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://boost.2283326.n4.nabble.com/range-cannot-use-lambda-predicate-in-adaptor-with-certain-algorithms-td3560157.html 和 https://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; })));
我已经询问(在推断lambda的调用签名或"make_function"的任意可调用)提供了一种编写make_function
的方法,以便可以只写:
*boost::min_element(
v | boost::adaptors::transformed(make_function(
[](int i) { return -i; })));
使用 C++17 要素类模板参数推导,您可以使用 std::函数简化器进行包装,如下所示:
*boost::min_element(
v | boost::adaptors::transformed(std::function(
[](int i) { return -i; })));