GSL では任意のパラメーターを渡すことができるため、これを悪用して問題のインスタンスへのポインターを保持できます。次に、静的メンバー関数を使用してメンバー関数に転送します。
class MyClass
{
double foo(double x)
{
...
}
static double foo_wrapper(double x, void *params)
{
return static_cast<MyClass*>(params)->foo(x);
}
double bar(double x)
{
...
gsl_function F;
F.function=&MyClass::foo_wrapper;
F.params=this;
// invoke GSL function passing in F
...
}
};
もっと上手にできますか?もっと簡単な方法はありますか?あまり。あなたがとるアプローチは、どこかで隠れてこれを行うことになります。
しかし、これのいくつかを隠す単純なラッパーを書くことができます:
class gsl_function_pp : public gsl_function
{
public:
gsl_function_pp(boost::function<double(double)> const& func) : _func(func)
{
function=&gsl_function_pp::invoke;
params=this;
}
private:
boost::function<double(double)> _func;
static double invoke(double x, void *params)
{
return static_cast<gsl_function_pp*>(params)->_func(x);
}
};
これにより、必要なタイプの機能が提供されます (複数の間接参照が原因でパフォーマンスが低下する可能性があります)。
class MyClass
{
double foo(double x)
{
...
}
double bar(double x)
{
gsl_function_pp F(boost::bind(&MyClass::foo, this, _1));
// invoke GSL function passing in F
...
}
};
注意点はgsl_function_pp
、GSL がオブジェクトを呼び出す可能性がある間、すべてのオブジェクトがスコープ内にあることを確認する必要があるということです。したがって、ある関数で (ローカルの gsl_function_pp を使用して) ルート ファインダー/etc を設定し、戻って、別の関数でルート検索の反復を実行しようとしないでください。クラッシュするか、さらに悪化します。