C++ 中的高阶函数:创建接受成员函数的积分器

imp*_*sso 2 c++ templates pointer-to-member higher-order-functions c++11

我想创建一个函数对象类,它可以按需在数字上集成一些函数。它的公共接口将包含一个void T::step(double dt)计算积分步骤的方法(并用新值更新函数对象的内部状态)和当前计算值的获取器。

虽然我确信这可以通过纯独立函数来完成,但我将要集成的函数有许多共同的中间计算步骤,并且依赖于许多内部参数,这些参数必须在每个步骤中更新(并且在很大程度上与用户),所以我想到使用函数对象来封装这个机制。

class myIntegrals
{
public:
  void step(double dt);
  double get_f1_integral() { return f1_integral; };
  double get_f2_integral() { return f2_integral; };

private:
  // funcs to be integrated (n.b. they share parameter/return types)
  double f1(double t); // depends on the state of member attributes;
  double f2(double t); // idem, and also on the results of f1

  double t;
  double f1_integral;
  double f2_integral;
  // and many internal parameters, updated on every step
}

void myIntegrals::step(double dt)
{
  // integrate `f1` from `t` to `t+dt`
  // process results, update internal parameters

  // integrate `f2` from `t` to `t+dt`, update internal parameters
  // process results, update internal parameters

  t += dt;
}
Run Code Online (Sandbox Code Playgroud)

但现在我发现自己正在与类型系统搏斗,试图定义一个函数double integrate(double t, double dt, METHOD f)来实际计算每个单独函数的集成步骤,接受成员函数作为参数。

我想出了

template <typename T>
double integrate(double t, double dt, double (T::*f)(double), T* obj)
{
  // Here I can reference `obj->*f(...)`
}
Run Code Online (Sandbox Code Playgroud)

但我有点不安,因为这似乎是做作的,而且有些人认为函数指针在性能方面是魔鬼。

仅使用 C++11 功能,是否有更干净、性能更高或更惯用的方法?

Nat*_*ica 7

integrate就我个人而言,我会通过采用Callable将对成员函数的调用卸载到调用站点。这迫使您在调用站点使用 lambda 表达式或自定义函子。就像是:

template <typename Callable>
double integrate(double t, double dt, Callable c)
{
    return c(t * dt);
}

double step(double) 
{ 
    return 42.0; 
}

struct MyCustomType {
    double step(double) 
    { 
        return 42.0; 
    }
};

int main()
{
    MyCustomType foo;
    // use member function via a lambda wrapper
    integrate(1, 2, [&](double param) { return foo.step(param); });
    
    // use regular function
    integrate(1, 2, step);
}
Run Code Online (Sandbox Code Playgroud)