1

I would like to integrate a function with gsl. Therefor I have to define a function f (the integrant, which has to be of the form double (*)(double, void*)). For the call of the gsl integration method I need to define a struct, which contains a pointer to a function (this struct is called gsl_function).

gsl_function F;
F.function = &MyClass::my_f;

The function f must be implemented in a class (in the same class from which the integration procedure should be called). How can I assign the pointer above correctly, since the 2nd line is not compiling and leads to the error:

cannot convert ‘double (MyClass::*)(double, void*)’ to ‘double (*)(double, void*)’ in assignment.

Here the definition of my_f

 struct my_f_params { double a; double b;};

   double my_f (double x, void * p) {
   struct my_f_params * params = (struct my_f_params *)p;
   double a = (params->a);
   double b = (params->b);
   return 1.0/(sqrt(a * (1.0 + x)*(1.0 + x)*(1.0 + x) + (1-a) * std::pow((1.0 + x), (3.0 * (1.0 + b))))); 
    }
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
johnhenry
  • 1,293
  • 5
  • 21
  • 43

1 Answers1

1

which has to be of the form double (*)(double, void*)

Non static member function declarations involve the implicit call scope qualifier as stated in the error message

double (MyClass::*)(double, void*)
     // ^^^^^^^^^

This is different from the callback function pointer definition.

What you probably can do with such interface, is to pass the this pointer through the void* argument of the callback function:

class MyClass {
    static double func(double d,void* thisPtr) {
        MyClass* myClass = (MyClass*)thisPtr;
        // do something
    }
};

As mentioned in the documentation you can set the params like that in a wrapper class:

class gsl_function_wrapper {
public:    
    gsl_function_wrapper() {
         F.function = &func;
         F.params = this;
    }
private:
    gsl_function F;

    double a;
    double b;

    static double func(double d,void* thisPtr) {
        gsl_function_wrapper* myWrapper = (gsl_function_wrapper*)thisPtr;
        // do something with a and b
        foo(d,myWrapper->a,myWrapper->b);
    }
};
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
  • Please provide correct citation to where you got this solution (it was not on the GSL website). Possible correct source - https://stackoverflow.com/a/18413206/2472169 – Vivian Miranda Nov 19 '17 at 01:49