由于 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
...
}
};
The caveat is that you'll have to ensure that any gsl_function_pp
object stays in scope for the entire time that the GSL might invoke it. So, don't try to set up a root finder/etc in one function (using a local gsl_function_pp), return, and then perform root finding iterations in another -- you'll get a crash or worse.