c++ - C++メンバー関数の非メンバーラッパーを「自動的に」作成する

原文 c++ wrapper

いくつかの数学演算を実行して結果を返すメンバー関数の束を持つクラスがあります。例えば:

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);
}


しかし、ラップする約12のメンバー関数fghなどがあり、後で追加する可能性があるため、これはかなり繰り返しになります。これらのラッパー関数を作成するために記述しなければならないコードの量を要約するために、テンプレートまたはマクロまたは何かを使用できますか(またはおそらくそうする必要がありますか)?



余談ですが、私が現在使用している解決策は、統合ルーチンをオブジェクトパラメータを直接受け入れる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プログラミングであり、マクロはそのために自然なものだからです。
関連記事

c++ - std::set_differenceセットキーとマップキーを比較することは可能ですか?

c++ - 配列をC++の関数に渡す

c++ - 述語ファンクタのパッケージ化

c++ - 空のBoostアキュムレータを使用する

c++ - VC++リソースコンパイラ(RC)オプション/ n…?

c++ - GL_DRAW_FRAMEBUFFERターゲットを使用すると、glBindFramebufferが「無効な操作」GLエラーを引き起こす

c++ - クラスのメンバーアクセス

c++ - ImageMagick C++ API出力16ビットグレースケールpng?

c++ - TWAINでサポートされている解像度を列挙するにはどうすればよいですか

c++ - C++入力が正しいかどうかをユーザーに尋ねるエラー