Alex
Alex

Reputation: 1177

In C++, how can you pass an object's method as a parameter to a function?

So, I have a function, called Romberg, that takes a function as first parameter:

int Romberg(double (*f)(double), ... );

When executed, it applies the passed function to several values.

In a class, I have defined the following methods:

double Funktion::q(double x){
    return(sqrt(1.0+fd(x)*fd(x)));
};
void Funktion::compute_bogen(){
    Romberg(q, ... );
};

Where fd is another method from the same class. This however, doesn't work! I tried altering the code in the following way, which ends up with successfully passing the method to the Romberg function; but then it fails to apply the passed function:

int Romberg(double (Funktion::* &f)(double), ... );

void Funktion::compute_bogen(){
    Romberg(&Funktion::q, ... );
};

I get the following error message:

error C2064: term does not evaluate to a function taking 1 arguments

Right now, I do not see how to make this work without throwing away the whole class system I built.

Upvotes: 2

Views: 293

Answers (2)

JRG
JRG

Reputation: 2135

I get the following error message:

error C2064: term does not evaluate to a function taking 1 arguments

This is because Funktion::q secretly takes 2 arguments, a this pointer and the double

The problem is that Romberg doesn't have any information about the object that calls it in Funktion::compute_bogen(), so it can't give it to Funktion::q(). You probably want something like this:

typedef double (Funktion::*RombergFuncArg)(double)

int
Romberg(RombergFuncArg func, Funktion& obj, ... )
{
   double input  = 0.0;
   double output = (obj.*func)(input);
   //...
}

[Edit] In reply to the comment:

void Funktion::compute_bogen(){
   Romberg(&Funktion::q, *this, ... );
};

Upvotes: 2

Jerry Coffin
Jerry Coffin

Reputation: 490713

To make it work with your class system, you need to define fd to take a pointer to a member function instead of a pointer to a function (the two are not the same).

Then you'll need to invoke it correctly for a pointer to a member function as well (which is slightly different than invoking a pointer to a function).

I'd note that although you can do this, you might be better off considering a somewhat different structure. One that's fairly common is to use a virtual function, which you'll override in various derived classes. Then instead of using a pointer to a member function, you select the object that implements the function you want, and invoke the virtual function in that object.

Upvotes: 1

Related Questions