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

Is it possible to change this code in order to avoid the use of the C++ lambda expression?

本文关键字:C++lambda 表达式 代码 是否      更新时间:2023-10-16

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

是。就像我们多年来在C++03中所做的那样:使用函数对象。

std::transform(以及类似算法)的大多数(如果不是全部的话)参考文献都有这样的例子。

在这种情况下,等价的函子是:

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捕获的任何内容都需要函子的相应数据成员。因此,"捕获所有内容"lambda有点棘手,因为您需要计算lambda实际使用的变量。lambda为您做的另一件事是,在lambda主体由单个返回语句组成的情况下,它会自动计算出返回类型。

可能包含语法或打字错误

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

只需拼写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()访问函数对象的工作。