您不能将类成员函数转换为 gsl_function without a wrapper。您必须使用全局函数。在这种情况下,如果您无法提供函数的一阶导数,则您链接的the GSL documentation 上显示的第二个示例是使用该库的标准方法(否则请检查第一个示例)。剩下的简化不多了。
但是,如果您愿意使用包装器,那么有很多方法可以简化您的生活。例如,您可以使用包装器to enable c++11 features like lambdas!。一般来说,我不建议任何人在没有仔细检查代码的情况下为 GSL 使用第三方包装器。您应该首先学习标准方法。
另一个例子:我开发了一个小包装器来简化 GSL 1D Root Finder API。您可以在 link 中找到源代码和一个很好的示例。我不是说你应该使用我的包装。随着时间的推移,您可能会开发自己的!
更新 1:还有O2Scl,它是我所知道的用于 gsl 的最发达的 C++ 包装器。它似乎有一个非常好的 API。再说一遍:你应该非常小心地使用包装器。
更新 2:回答评论中提出的问题:您还可以创建一个全局函数并将其用作包装器。示例:
double myFunction(double x, void* ptr) {
myClass* ptr2 = static_cast<myClass*>(ptr);
return ptr2->myFunction(x);
}
在更复杂的情况下我不喜欢这个解决方案(但这里非常好,可能是更简单的选项)因为如果你想发送更多参数会很麻烦(例如:你需要 2 个参数:类本身和一个额外的数字 - 在这种情况下,您需要创建一个额外的结构来容纳两者!)。使用我链接的包装器,您可以使用 lambdas 轻松发送许多参数!示例
double a = 1;
myClass m1 ....
gsl_function_pp Fp( [&](double x){return a * m1.myFunction(x);} );
gsl_function *F = static_cast<gsl_function*>(&Fp);
只是为了完成,这里是包装代码
class gsl_function_pp : public gsl_function
{
public:
gsl_function_pp(std::function<double(double)> const& func) : _func(func){
function=&gsl_function_pp::invoke;
params=this;
}
private:
std::function<double(double)> _func;
static double invoke(double x, void *params) {
return static_cast<gsl_function_pp*>(params)->_func(x);
}
};