是否可以更改此代码以避免使用C ++ lambda表达式?

时间:2011-06-20 09:00:39

标签: c++ lambda

我有这段代码,我想知道我是否可以更改它以避免使用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。

4 个答案:

答案 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()

访问函数对象的工作