开发者

Calling the function pointed by a Pointer-to-Member-Function from within a struct

开发者 https://www.devze.com 2023-03-23 02:04 出处:网络
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:

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)) ();
0

精彩评论

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