«Автоматически» создание не членских оболочек для функций-членов C ++ - PullRequest
2 голосов
/ 14 октября 2011

У меня есть класс с кучей функций-членов, которые выполняют некоторые математические операции и возвращают результат. Например:

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 и т. Д. Для переноса, и, возможно, еще больше будет добавлено позже, это становится довольно повторяющимся. Может ли (или, возможно, должен ) использовать шаблон или макрос или что-то еще, чтобы сократить объем кода, который мне нужно написать, чтобы создать эти функции-оболочки?


Кроме того, в настоящее время я использую решение - переопределить подпрограмму интеграции как шаблон функции C ++, который напрямую принимает параметр объекта:

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

но это включает в себя крупномасштабное дублирование кода, что мне не нравится. Если у кого-то есть лучшее решение, чем создание функций-оболочек или реализация версии интегратора на C ++, мне было бы интересно услышать его, и я могу задать отдельный вопрос, если это будет более уместным.

1 Ответ

2 голосов
/ 14 октября 2011

Вы можете попробовать это с шаблонами:

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, и макросы для этого естественны.

...