"Automatically"为C++成员函数创建非成员包装器

"Automatically" creating non-member wrappers for C++ member functions

本文关键字:成员 包装 创建 函数 C++ Automatically      更新时间:2023-10-16

我有一个类,它有一堆成员函数,这些函数做一些数学运算并返回结果。例如:

class Foo {
public:
  double f(double);
  double g(double);
  double h(double);
  // ...
}
double Foo::f(double foo1) {
  // ...
}
// and so on

在我正在编写的程序中,我需要对其中一些函数进行数值积分。我想使用的数值积分例程具有签名

extern "C" double qgauss(double (*func)(double, void*), void* data,
                         double a, double b);

,从我一直在阅读,似乎最好的方式来传递成员函数的集成例程是创建包装器函数:

double f_wrapper(double x, void* data) {
    return ((Foo*)data)->f(x);
}

但是由于大约有十几个成员函数f, g, h等要包装,并且可能稍后还要添加更多,这变得相当重复。我可以(或者也许应该)使用模板或宏或其他东西来压缩为了创建这些包装器函数而必须编写的代码量吗?


作为题外话,我目前使用的解决方案是将集成例程重新实现为直接接受object参数的c++函数模板:
template <class C> double qgauss(C* obj, double (C::*func)(double),
                                 double a, double b) {
  // ...
}

但是这涉及到大规模的代码重复,这是我不喜欢的。如果有人有比创建包装器函数或实现c++版本的集成器更好的解决方案,我很有兴趣听到它,如果这样更合适,我可以问一个单独的问题。

您可以尝试使用模板:

template <class C, C::*Func>
double wrapper(double x, void* data) {
    return ((C*)data)->*Func(x);
}
qgauss(&wrapper<C, &C::f>, data, a, b);

现在,我还没有尝试过,可能会有一些问题,因为你想要一个函数的地址,这是一个模板——更糟糕的是,我认为你在技术上需要一个extern "C"函数。如果以上确实是一个死胡同,我认为您应该只使用宏,因为毕竟这是C编程,在这一点上,宏是自然的。