我有这段代码,我想知道我是否可以更改它以避免使用lambda表达式:
#include <vector>
#include <algorithm>
#include <iterator>
class B
{
public:
B( double b ):b_(b){}
double b_;
};
class A
{
public:
double error( const B& b ) const {return a_-b.b_;};
double a_;
};
int main(int argc, char* argv[])
{
std::vector< B > bs;
std::vector< double > ds;
A a;
a.a_ = 10;
bs.push_back( B(1) );
bs.push_back( B(2) );
bs.push_back( B(3) );
std::transform( bs.begin(), bs.end(),
std::back_inserter( ds ),
[&a](const B& b){return a.error(b);} );
return 0;
}
我想保留std::transform
但没有lambda。
答案 0 :(得分:5)
是。就像我们多年来在C ++ 03中所做的一样:使用函数对象。
std::transform
(和类似算法)的大多数(如果不是全部)参考都会有这样的例子。
答案 1 :(得分:4)
在这种情况下,等效的函子是:
struct CallError {
A &a;
CallError(A &a) : a(a) {}
double operator()(const B &b) { return a.error(b); }
};
然后:
std::transform( bs.begin(), bs.end(),
std::back_inserter( ds ),
CallError(a));
请注意,lambda捕获的任何内容都需要仿函数的相应数据成员。因此,“捕获所有内容”lambdas有点棘手,因为您需要确定lambda实际使用的变量。 lambda为你做的另一件事,在这种情况下,lambda主体由一个return语句组成,它会自动计算出返回类型。
答案 2 :(得分:2)
可能包含语法或拼写错误
double fn(const A &a, const B &b) {
return a.error(b);
}
....
using std::placeholders::_1;
std::transform( bs.begin(), bs.end(),
std::back_inserter( ds ),
boost::bind(fn, a, _1) );
答案 3 :(得分:1)
简单说出Tomalak的回答:
struct ErrorFunctor {
double a;
ErrorFunctor(double a) : a(a) { }
inline double operator()(const B & b) const { return a - b.b_; }
};
// ... later on ...
std::transform(bs.begin(), bs.end(), std::back_inserter(ds), ErrorFunctor(10));
必须通过operator()
。