1

In my code I would like to call different functions by the same name. So I used pointers, and I did work with static functions, now I would like to do the same with non-static functions and it doesn't work at all.

class Amrorder
:   {
public:
   ....
    void (*fkt)(real&, const real);
    void fktAcPulse(real &rhoRef, const real y);
    void fktAcPulseSol(real &rhoRef, const real y);
...
}

void Amrorder::initData(a)
{
...
 switch(method){
    case 2://
      Amrorder::fkt=&Amrorder::fktAcPulse;
      break;
    case 222://
      Amrorder::fkt=&Amrorder::fktAcPulse1d;
      break;
    }
...
  for(int i=0; i<ng; ++i){ 
    Amrorder::fkt(rhoRef, yRef);
    ...
  }
...
}

The code is quiet big so I hope the part above is enough to understand what I want to do.

Thanks for your time!

5
  • What errors are you seeing? Commented Nov 10, 2015 at 15:53
  • Learn C++11 and learn about closures and lambdas i.e. anonymous functions. See also std::function Commented Nov 10, 2015 at 15:54
  • A pointer to a non-member function is not the same as a pointer to a non-static member function. Your variable fkt is a pointer to a non-member function. Commented Nov 10, 2015 at 15:57
  • 4
    Look up syntax for "pointer-to-member function". Commented Nov 10, 2015 at 15:57
  • Required reading: parashift.com/c++-faq/pointers-to-members.html (It might be a bit old-fashioned with C++11 around, but is still required). Commented Nov 10, 2015 at 16:00

3 Answers 3

1

It doesn't work because your fkt has type:

void (*)(real&, const real);

and you're trying to assign it to, e.g., &Amrorder::fktAcPulse, which has type:

void (Amrorder::*)(real&, const real);

Notice the difference. The latter is a pointer-to-member function, not just a pointer to function. These have different semantics. A pointer to function can just be called (e.g. fkt(a, b)), but a pointer to member function needs to be called on an object (e.g. (obj.*pm)(a, b)).

For simplicity, since you probably just want "something that I can call with a real& and a const real", you may want to consider the type-erased function object: std::function:

std::function<void(real&, const real)> fkt;

This can be initialized with any callable that matches the arguments, so you can assign it to a free function:

void foo(real&, const real) { ... }
fkt = foo;

A static member function:

struct S { static void bar(real&, const real) { ... } };
fkt = &S::bar;

Or a member function, as long as its bound:

fkt = std::bind(&Amrorder::fktAcPulse, this);
fkt = [this](real& a, const real b){ return this->fktAcPulse(a, b); };

The key is that you need an instance of Amrorder to call fktAcPulse, and using std::function lets you use either std::bind or a lambda to store that instance in with the functor itself.

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

Comments

0

The type of fkt declares a function pointer to a free-standing function or a static member function. But you want to assign a non-static member function pointer to it. So fkt needs to be of the type of a non-static member function pointer of class Amrorder. That type is spelled

void (Amrorder::*fkt)(real&, const real);
//    ^^^^^^^^^^

When invoking a function pointer to a non-static member function, you need to specify on which object you want the member to be called (which normally defaults to this when calling a member function directly with its name).

The syntax for this is quite strange. It requires another pair of parentheses and depends on wether you call it on a pointer or an object itself:

(object.*functionPointer)(arguments);
(pointer->*functionPointer)(arguments);

So if you just want to call the function on the this pointer, you need to write

(this->*fkt)(rhoRef, yRef);

(Note that you don't need to specify the class in your code everywhere. Amrorder:: can be removed in front of every function name inside the definition of a member function of the same class.)

1 Comment

Even so this looks quiet strange to me, it dose exactly what I want. So thank you!!
0

When you call a non-static method of a class, the compiler needs to know which instance of the class you want to execute against. So there is a hidden parameter in the call, which is a pointer to the instance.

So you need to write something like this:

Amrorder::fkt=bind( &Amrorder::fktAcPulse, this );

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.