2

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?

5 Answers 5

5

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();

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

1 Comment

You could make the function static. Then Base::*fp(); (up vote)
2

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.

Comments

1
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.

Comments

1

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.

5 Comments

Roberts I can't see a point of using pointers to member function in that case. Why wouldn't I use the pointer to my base class and invoke any function without using this pointer to member function?
@There For the same reason, why you would use function pointer. Dynamic binding to a specific method.
@There if you know what function to call inside a class then using object (something.fnc()) is the way to go, but if you don't know the function then you need both the object and pointer to member function (something.*fp()). Those p-to-m-f's are sometimes handy, but are rarely used.
I certainly would not agree that pointer to member is a rarely used construct. If you're adequately leveraging the STL you're probably using it a lot.
std::for_each(shapes.begin(), shapes.end(), std::mem_fun(&Shape::draw));
1

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))

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.