callback vs lambda

callback vs lambda

本文关键字:lambda vs callback      更新时间:2023-10-16

假设我有以下希望重构的代码:

int toFuture()
{
  precalc();
  int calc = 5 * foobar_x() + 3;
  postcalc();
  return calc;
}
int toPast()
{
  precalc();
  int calc = 5 * foobar_y() - 9;
  postcalc();
  return calc;
}

在classic-C中,我会将这段代码重构为一个worker(),它接受一个函数指针来进行计算:worker()中的通用代码,函数指针提供的特定代码。

在c++ 11中,我应该使用lambda代替吗?如果是,在这种情况下,我该如何实现它?

编辑:我刚想到一个模板也可以工作。模板实现与其他两种相比如何?

一种方法:

template<typename CalcFuncT>
int perform_calc(CalcFuncT&& calcfunc)
{
    precalc();
    int const calc = std::forward<CalcFuncT>(calcfunc)();
    postcalc();
    return calc;
}
int main()
{
    perform_calc([]{ return 5 * foobar_x() + 3; }); // toFuture
    perform_calc([]{ return 5 * foobar_y() - 9; }); // toPast
}

如果您想要使用c++ 11特性的模板方法,可以像下面这样简单:

template<typename FuncType>
auto calculation(FuncType&& func) -> decltype(func())
{
    precalc();
    auto ret = func();
    postcalc();
    return ret;
}

你只需调用你的calculation函数并传递给它一个lambda、一个函子或一个函数指针。在这种情况下,您唯一的困难来源是如果您传递了一个具有void返回类型的函数……在这种情况下,您将得到一个编译器错误(这是一件好事,而不是运行时错误)。

我觉得你重构的方向错了:

struct CalcGuard {
  CalcGuard() { /* replaces precalc() */ }
  ~CalcGuard() { /* replaces postcalc() */ }
};
int toFuture()
{
  return CalcGuard(), calc = 5 * foobar_x() + 3;
}
int toPast()
{
  return CalcGuard(), calc = 5 * foobar_y() - 9;
}

有一种C/C++方法可以做到这一点,还有一种C++11方法。这两种方式都不涉及lambda或模板。

C/C++方式:

double MyFunc (int x, float y) { return x + y ; }
int main()
  {
  double (*pf) (int, float) ;
  pf = MyFunc ;
  pf (101, 202.0) ;
  }

C++11方式:

#include <functional>
double MyFunc (int x, float y) { return x + y ; }
int main()
  {
  std::function<double (int, float)> f ;
  f = MyFunc ;
  f (51, 52.0) ;
  }

无论哪种情况,您只需将pff作为参数传递给重构函数。在这里使用lambdas或模板是多余的。