2

在下面的代码中(请参阅评论):

#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 个参数的函数”为什么它不起作用以及如何修复它?

4

5 回答 5

5

它不起作用,因为fp它不是函数指针而是成员指针。

如何修复它很容易,按它应该使用的方式使用它:someinstance.*fp();

于 2010-10-25T17:08:53.610 回答
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。但代价是您可能会收到难以理解的编译器错误消息。

于 2010-10-25T17:44:49.437 回答
1

您需要一个 Base 来调用该函数。

您可能正在寻找更类似于 bind() 和 function<> 的东西,它们允许您将实例和成员函数绑定到可以像函数一样调用的仿函数中。

于 2010-10-25T17:05:36.627 回答
1
typedef  int (MyClass::*memberPointer_t)(int);

...

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

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

...

由于它是指向成员函数的指针,因此您必须在对象上调用它并使用 ->* 或 .* 运算符来调用它。

于 2010-10-25T17:24:18.037 回答
1

您可以从阅读有关指向成员函数的指针的常见问题解答中受益。特别是他们强烈建议您为这些调用定义一个宏:

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

于 2010-10-25T17:28:22.993 回答