[C++] Pointers to member functions

In summary, the programmer is having trouble integrating the GNU Scientific Library into their code. They are trying to pass a pointer-to-member function to the GSL routines, but they are of a different type than a pointer-to-function. He suggests writing a wrapper class that has a static member function of the type required by GSL, and that takes as an input your function class.
  • #1
Wallace
Science Advisor
1,256
0
Hi, I was hoping a C++ guru could help me with a problem I'm having using the gnu science library (gsl) in my C++ code. Here is my issue:

Take for instance the Runge Kutter codes for solving differential equations. You need to supply the gsl routines for this a pointer to a function describing the derivatives of the system. In many cases I would like this function to be a member function of some class I have defined. However, since pointers to member functions are not the same as pointers to functions, when I try and do this I get an error.

This is annoying as it means all of these functions have to sit outside classes and especially annoying as these functions need to access many members of the classes they would ideally be members of in working out the derivatives. At present I need to use variables of global scope in order to get information into these functions which is annoying and ugly in a C++ context.

What I would love to know is how to make the gsl routines accept pointers to member functions, if this is at all possible. I know enough about this issue to realize what is causing the error when I give the gsl routines a pointer to a member function, but I have no idea how to resolve this issue, if it is even possible, which I certainly hope it is!

To be clear, here is a concrete example of my problem. Take the example ODE code http://www.gnu.org/software/gsl/manual/html_node/ODE-Example-programs.html" . The stepper function needs an object 'sys' defined by

gsl_odeiv_system sys = {func, jac, 2, &mu};

where func and jac are pointers to functions. The func given in this example for instance is

int
func (double t, const double y[], double f[],
void *params)
{
double mu = *(double *)params;
f[0] = y[1];
f[1] = -y[0] - mu*y[1]*(y[0]*y[0] - 1);
return GSL_SUCCESS;
}

What I want to do is provide a 'func' that is a pointer to a member function of an instantiated object. This is because the func needs to know a lot of information that is contained in that object. In this case a bunch of splines as well as some other functions. It is painful to have to make all of these have global scope just so this function can see them.

Can anyone suggest a solution? I would be most appreciative!
 
Last edited by a moderator:
Technology news on Phys.org
  • #2
I feel your pain, I wasted many hours trying to integrate GSL into my C++ code. There is no way that you can pass a pointer-to-member function to the GSL routines because they are of a different type than a pointer-to-function. For example, for the function:

double func(double, void*)

the type will vary depending on whether it is an ordinary function, a non-static member function of some class, or a static member function of a class.

- It is of type double (*)(double, void*) if it's an ordinary function or a static member function of a class.

- It is of type double (MyClass::*)(double, void*) if it's a non-static member function of class MyClass

The trick to working with C++ and GSL is to write a wrapper class that has a static member function of the type required by GSL, and that takes as an input your function class.

As an example, I wrote a quick and dirty solver class which used the root finding algorithms in GSL. To do so, I used the following function wrapper class which is initialised with a class containing the function I want to solve (this class is assumed to provide operator(double)) and the value I am trying to solve for.

template <typename T>
class FunctionWrapper : private boost::noncopyable {
public:
static void initialise(const boost::shared_ptr<T>& funcPtr, double target = 0) {
_funcPtr = funcPtr;
_target = target;
}

static double evaluate(double x, void* params) {

return _funcPtr->operator()(x) - _target;
}

protected:
FunctionWrapper() {}

private:
static boost::shared_ptr<T> _funcPtr;
static double _target;
};

template <typename T>
boost::shared_ptr<T> FunctionWrapper<T>::_funcPtr;

template <typename T>
double FunctionWrapper<T>::_target;


My wrapper class and GSL function are then initialised as follows:

gsl_function F;

FunctionWrapper<FunctionType>::initialise(funcPtr, target);
F.function = FunctionWrapper<FunctionType>::evaluate;
F.params = NULL;

I'm a little short on time at the moment, but hopefully the above makes some sense and the formatting isn't too messed up. Let me know if you have any further problems.
 
  • #3
Thanks! I must admit I don't follow precisely a lot of the code you posted, I haven't got to using templates etc very much yet (still a C++ newb really) although I get the jist of what you are suggesting. I think I can work it out from your advice and the code, I'll let you know if I run into problems I can't solve.

Thanks again for your help!
 

1. What are pointers to member functions in C++?

Pointers to member functions in C++ are special types of pointers that are used to store the memory address of a class member function. They allow us to access and call a particular member function of an object at runtime.

2. How do you declare a pointer to a member function in C++?

To declare a pointer to a member function in C++, you need to specify the class name, followed by the scope resolution operator (::), the pointer name, and the function's return type and parameters. For example, int (ClassName::*ptr)(int, int); declares a pointer to a member function called ptr that takes two int parameters and returns an int.

3. How do you assign a member function to a pointer in C++?

You can assign a member function to a pointer in C++ by using the address-of operator (&) before the function name. For example, ptr = &ClassName::memberFunction; assigns the memberFunction of ClassName to the pointer ptr.

4. What is the purpose of using pointers to member functions in C++?

Pointers to member functions are used in C++ to achieve polymorphism, which allows different objects to respond to the same function call in different ways. They also allow us to call a particular member function of an object at runtime, providing flexibility and dynamic behavior in our code.

5. Can pointers to member functions be called directly?

No, pointers to member functions cannot be called directly in C++. They need to be dereferenced and invoked through an object or pointer to an object. The syntax for calling a member function through a pointer is object.*ptr() or pointer->*ptr(), where object is an instance of the class and pointer is a pointer to an instance of the class.

Similar threads

  • Programming and Computer Science
Replies
11
Views
1K
  • Programming and Computer Science
Replies
6
Views
917
  • Programming and Computer Science
Replies
12
Views
1K
  • Programming and Computer Science
2
Replies
40
Views
2K
  • Programming and Computer Science
Replies
7
Views
1K
  • Programming and Computer Science
Replies
19
Views
2K
  • Programming and Computer Science
Replies
14
Views
2K
  • Programming and Computer Science
Replies
2
Views
684
  • Programming and Computer Science
Replies
5
Views
812
  • Programming and Computer Science
Replies
17
Views
2K
Back
Top