2

这个问题似乎已经被问过很多次了,例如here1here2here3

我想要做的是,将functionC-Struct的成员设置gsl_function为我的类的成员函数。

class MyClass{

    double foo(double x)
    {
        return ...;
    }

    double bar(double x)
    {
        ...
        gsl_function F;
        // Problem I cant do this (compiler error)
        F.function = &(this->foo);
    }
};

上面的第三个链接提供了一个解决方案,我认为它基于此处描述的包装器方法4

所以我的问题是我能做得更好吗?有没有更简单的方法?例如,可能通过使用 Boost 的函数和 Bind 对象。

我正在权衡使用 gsl 包装器的选项,例如 o2scl。但是我有点不情愿,因为如果包装纸维护不好,我可能会在以后付出代价。有什么建议么?

4

1 回答 1

7

由于 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.

于 2012-05-15T04:30:44.660 回答