开发者

Problem with pointer to a member function

开发者 https://www.devze.com 2023-01-22 09:40 出处:网络
In code below (please see comment): #include \"stdafx.h\" #include <iostream> using std::cout; 开发者_开发知识库struct Base

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

0

精彩评论

暂无评论...
验证码 换一张
取 消