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, pmf_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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With