[英]boost transform iterator and c++11 lambda
I'm trying to use boost::adaptors::transformed by providing a c++0x lambda to the adaptor. 我试图通过向适配器提供c ++ 0x lambda来使用boost :: adapters :: transformed。
The following code does not compile. 以下代码无法编译。 I'm using g++ 4.6.2 with boost 1.48. 我正在使用g ++ 4.6.2和boost 1.48。
#include <iostream>
#include <vector>
#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm.hpp>
using namespace std;
namespace br = boost::range;
namespace badpt = boost::adaptors;
int main()
{
vector<int> a = {0,3,1,};
vector<int> b = {100,200,300,400};
auto my_ftor = [&b](int r)->int{return b[r];};
cout<<*br::max_element(a|badpt::transformed(my_ftor))<<endl;
}
Any ideas on what I'm doing wrong here? 关于我在这里做错了什么的想法?
It's well known issue. 这是众所周知的问题。 Look here 看这里
http://boost.2283326.n4.nabble.com/range-cannot-use-lambda-predicate-in-adaptor-with-certain-algorithms-td3560157.html http://boost.2283326.n4.nabble.com/range-cannot-use-lambda-predicate-in-adaptor-with-certain-algorithms-td3560157.html
Shortly, you should use this macro 不久,你应该使用这个宏
#define BOOST_RESULT_OF_USE_DECLTYPE
for use decltype
instead of boost::result_of
. 使用decltype
而不是boost::result_of
。
If your compiler supports decltype, then you can enable automatic result type deduction by defining the macro BOOST_RESULT_OF_USE_DECLTYPE, as in the following example. 如果您的编译器支持decltype,那么您可以通过定义宏BOOST_RESULT_OF_USE_DECLTYPE来启用自动结果类型推导,如下例所示。
Well lambdas don't play nice, since they are not default constructible, which is necessary for iterators. Lambdas不好玩,因为它们不是默认构造的,这对迭代器来说是必要的。 Here is a wrapper I use for lambdas: 这是我用于lambdas的包装器:
#define RETURNS(...) -> decltype(__VA_ARGS__) { return (__VA_ARGS__); }
template<class Fun>
struct function_object
{
boost::optional<Fun> f;
function_object()
{}
function_object(Fun f): f(f)
{}
function_object(const function_object & rhs) : f(rhs.f)
{}
// Assignment operator is just a copy construction, which does not provide
// the strong exception guarantee.
function_object& operator=(const function_object& rhs)
{
if (this != &rhs)
{
this->~function_object();
new (this) function_object(rhs);
}
return *this;
}
template<class F>
struct result
{};
template<class F, class T>
struct result<F(T)>
{
typedef decltype(std::declval<Fun>()(std::declval<T>())) type;
};
template<class T>
auto operator()(T && x) const RETURNS((*f)(std::forward<T>(x)))
template<class T>
auto operator()(T && x) RETURNS((*f)(std::forward<T>(x)))
};
template<class F>
function_object<F> make_function_object(F f)
{
return function_object<F>(f);
}
Then you can just do this: 然后你可以这样做:
int main()
{
vector<int> a = {0,3,1,};
vector<int> b = {100,200,300,400};
cout<<*br::max_element(a|badpt::transformed(make_function_object([&b](int r)->int{return b[r];};)))<<endl;
}
@ForEver's answer ( #define BOOST_RESULT_OF_USE_DECLTYPE
) didn't work for me. @ ForEver的答案( #define BOOST_RESULT_OF_USE_DECLTYPE
)对我不起作用。 And @Paul's answer is too long (and too general). 而@Paul的回答太长了(而且太笼统)。 A more specific solution can be this: 更具体的解决方案可以是:
#include <iostream>
#include <vector>
#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm.hpp>
using namespace std;
namespace br = boost::range;
namespace badpt = boost::adaptors;
int main()
{
vector<int> a = {0,3,1,};
vector<int> b = {100,200,300,400};
struct{
vector<int>* bP; //pointer, just to imitate lambda syntax...
int operator()(int r) const{return (*bP)[r];} //was my_ftor = [&b](int r)->int{return b[r];};
} my_ftor{&b}; //...here
cout<<*br::max_element(a|badpt::transformed(my_ftor))<<endl;
}
(It is 2016, Boost 1.58 and this is still broken. At least lambda without captures should fulfill the requirements of boost::transformed
.) (这是2016年,Boost 1.58,这仍然是破碎的。至少没有捕获的lambda应该满足boost::transformed
的要求。)
If the lambda didn't have a capture (not your case) the code would be a bit simpler OR you could use: 如果lambda没有捕获(不是你的情况),代码会更简单一点,或者你可以使用:
...
int(*my_ftor)(int) = [](int r)->int{return ...;}; // function pointer default constructible and callable
cout<<*br::max_element(a|badpt::transformed(my_ftor))<<endl;
...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.