开发者

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

开发者 https://www.devze.com 2023-04-13 02:10 出处:网络
I have a class with a bunch of member functions which do some mathematical operation and return a result. For example:

I have a class with a bunch of member functions which do some mathematical operation and return a result. For example:

class Foo {
public:
  double f(double);
  double g(double);
  double h(double);
  // ...
}

double Foo::f(double foo1) {
  // ...
}
// and so on

At several points in the program I'm working on, I need to numerically integrate some of these functions. The numerical integration routine I'd like to use has the signature

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

and from what I've been reading it seems that the best way to pass the member functions to the integration routine is to create wrapper functions:

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

But with about a dozen member functions f, g, h, etc. to wrap, and perhaps more to be added later, this gets pretty repetitive. Can (or perhaps should) I use a template or macro or something to condense the amount of code I have to write in order to create th开发者_如何转开发ese wrapper functions?


As an aside, the solution I'm currently using is to reimplement the integration routine as a C++ function template that accepts the object parameter directly:

template <class C> double qgauss(C* obj, double (C::*func)(double),
                                 double a, double b) {
  // ...
}

but this involves large-scale duplication of code, which I don't like. If anyone has a better solution than either creating wrapper functions or implementing a C++ version of the integrator, I would be interested to hear it and I can ask a separate question if that would be more appropriate.


You could try it with templates:

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

qgauss(&wrapper<C, &C::f>, data, a, b);

Now, I haven't tried this, and there may be some issue because you want the address of a function which is a template--and worse yet I think you technically need an extern "C" function. If the above is indeed a dead end, I think you should just use macros, as after all this is C programming you're doing at this point, and macros are natural for that.

0

精彩评论

暂无评论...
验证码 换一张
取 消