Calling the function pointed by a Pointer-to-Member-Function from within a struct
I have a class Test
with a peculiar data structure.
A member of class Test
is a std::map
where the key is a std::string
and the mapped value is a struct
defined as follows:
typedef struct {
void (Test::*f) (void) const;
} pmf_t;
Initialization of the map is OK. The problem is when I am trying to call the function pointed. I made up a toy example reproducing the problem. Here it is:
#include <iostream>
#include <map>
using namespace std;
class Test;
typedef void (Test::*F) (void) const;
typedef struct {
F f;
} pmf_t;
class Test
{
public:
Test () {
pmf_t pmf = {
&Test::Func
};
m["key"] = pmf;
}
void Func (void) const {
cout << "test" << endl;
}
void CallFunc (void) {
std::map<std::string, pmf_t>::iterator it = m.begin ();
((*it).second.*f) (); // offending line
}
std::map<std::string, p开发者_运维技巧mf_t> m;
};
int main ()
{
Test t;
t.CallFunc ();
return 0;
}
Thanks in advance, Jir
The name of the pmf_t
type is f
, so the first change is to remove the *
to get second.f
. That gives you a pointer-to-member value. To use a pointer-to-member, you need an instance. The only one you have available of the correct type is this
, so use it with the ->*
operator:
(this->*it->second.f)();
You need parentheses around the whole thing, or else the compiler thinks you're trying to call it->second.f()
(which isn't allowed) and then applying the result to ->*
.
The offending line is trying to call a member function without any object to call it on. If the intention is to call it for the this
object, I believe the call should look like
( this->* ((*it).second.f) )();
Where this->*
is the syntax for dereferencing a pointer-to-member for the current object. ((*it).second.f)
is the pointer retrieved from the map, and ()
is the call operator for actually calling the function.
This is perhaps good as an exercise, but otherwise of limited use.
I think you might want to check out the C++ FAQ on this one. The syntax is apparently pretty tricky to get right (they actually recommend using a macro).
It might be too late for this question but, the seemingly complex synatax can be break down to two simple lines so it looks pretty clear:
void CallFunc (void)
{
pmf_t t = m["key"]; //1>get the data from key
(this->*t.f)(); //2>standard procedure to call pointer to member function
}
try this:
(this->*((*it).second.f)) ();
精彩评论