Question

In code below (please see comment):

#include "stdafx.h"

#include <iostream>
using std::cout;

struct Base
{
 void fnc()
 {
  cout << "Base::fnc()";
 }

};

struct Impl
{
 void* data_;
 Impl(void (Base::*fp)())
 {
  fp();//HERE I'M INVOKING IT - I'M DOING SOMETHING WRONG!
 }
};
int _tmain(int argc, _TCHAR* argv[])
{
 return 0;
}  

Error
"Error 1 error C2064: term does not evaluate to a function taking 0 arguments" Why doesn't it work and how to fix it?

Was it helpful?

Solution

typedef  int (MyClass::*memberPointer_t)(int);

...

memberPointer_t mb = &MyClass::function;
MyClass* object = getObject();

int returnValue = (object->*mb)(3);

...

Since it's a pointer to a member function, you must call it on an object and use the ->* or the .* operator to call it.

OTHER TIPS

It doesn't work because fp is not a function pointer but a member pointer.

How to fix it is easy, use it as it should be used: someinstance.*fp();

The problem is that you are calling the function as a free function, when it isn't. It's a member function, and you need to call it in the context of an object:

(obj.*f)();

Boost.Bind offers an idiomatic way to tackle this:

#include<boost/bind.hpp>

// ...
Impl i(boost::bind(&Base::fnc, obj));

You can define the Impl constructor like so:

#include<boost/function.hpp>

// ...
Impl(boost::function<void ()> fnc)
{
    fnc();  // boost::bind translates it to obj.fnc()
}

If only the Impl object knows what object to call the function on, then you can use the placeholders of Boost.Bind:

Impl i(boost::bind(&Base::fnc, boost::_1));

And the Impl constructor would then be similar to

Impl(boost::function<void (Base)> fnc, Base& b)
{
    fnc(b);  // boost::bind translates it to b.fnc()
}

Sometimes it's wiser to use templates in the side that accepts the functor:

template<class Op>
Impl(Op fnc) { ... }

because then the client can pass any member function, with or without boost. But the cost is that you might have harder-to-understand compiler error messages.

You need a Base to call the function on.

You might be looking for something more like bind() and function<> that will allow you to bind an instance and member function into a functor that can be just called like a function.

You could benefit from reading this FAQ regarding pointers to member functions. Particularly they strongly recommend you define a macro for these calls:

#define CALL_MEMBER_FN(object,ptrToMember) ((object).*(ptrToMember))

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top