2

This question seems to have been asked numerous times before, for example here1, here2 and here3.

What I am trying to do is, set the member function of the C-Struct gsl_function to a member function of my class.

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

The third link above provides a solution, I think it is based on the wrapper approach described here4.

So my question is can I do better. Is there an easier way? For example, possibly by using Boost's function and Bind objects.

I am weighing up the option of using a gsl wrapper, such as o2scl. But am a bit releuctant as I may pay the price later if the wrapper is not well maintained. Any suggestions?

0

1 Answer 1

7

Since GSL allows you to pass in arbitrary parameters, you can abuse this to hold the pointer to the instance under question. Then use a static member function to forward to the member function:

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

Can you do better? Is there an easier way? Not really. Any approach you take will be doing this under the covers somewhere.

But you can write a simple wrapper which hides some of this:

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

This should give you (possibly at a moderate performance penalty due to multiple indirections involved) the type of functionality you'd want:

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.