在下面的代码中(请参阅评论):
#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;
}
错误
“错误1错误C2064:术语不评估为采用0参数的函数”
为什么它不起作用以及如何解决它?
答案 0 :(得分:5)
它不起作用,因为fp
不是函数指针而是成员指针。
如何修复它很容易,请使用它:someinstance.*fp();
答案 1 :(得分:2)
问题是你将函数作为自由函数调用,而不是。它是一个成员函数,您需要在对象的上下文中调用它:
(obj.*f)();
Boost.Bind提供了解决这个问题的惯用方法:
#include<boost/bind.hpp>
// ...
Impl i(boost::bind(&Base::fnc, obj));
您可以像这样定义Impl
构造函数:
#include<boost/function.hpp>
// ...
Impl(boost::function<void ()> fnc)
{
fnc(); // boost::bind translates it to obj.fnc()
}
如果只有Impl
对象知道要调用该函数的对象,则可以使用Boost.Bind的占位符:
Impl i(boost::bind(&Base::fnc, boost::_1));
然后Impl
构造函数将类似于
Impl(boost::function<void (Base)> fnc, Base& b)
{
fnc(b); // boost::bind translates it to b.fnc()
}
有时在接受仿函数的一方使用模板更明智:
template<class Op>
Impl(Op fnc) { ... }
因为那时客户端可以传递任何成员函数,有或没有boost。但成本是您可能难以理解编译器错误消息。
答案 2 :(得分:1)
你需要一个Base来调用该函数。
你可能正在寻找更像bind()和function&lt;&gt;的东西这将允许您将实例和成员函数绑定到一个可以像函数一样调用的仿函数。
答案 3 :(得分:1)
typedef int (MyClass::*memberPointer_t)(int);
...
memberPointer_t mb = &MyClass::function;
MyClass* object = getObject();
int returnValue = (object->*mb)(3);
...
由于它是指向成员函数的指针,因此必须在对象上调用它并使用 - &gt; *或。*运算符来调用它。
答案 4 :(得分:1)
您可以阅读有关成员函数指针的this常见问题解答。 特别是他们强烈建议您为这些调用定义一个宏:
#define CALL_MEMBER_FN(object,ptrToMember) ((object).*(ptrToMember))