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?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.
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.
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))
精彩评论