从结构中调用由指针到成员函数指向的函数

时间:2011-07-27 15:07:12

标签: c++ pointer-to-member

我有一个具有特殊数据结构的类Test。 类Test的成员是std::map,其中键为std::string,映射值为struct,其定义如下:

typedef struct {
  void (Test::*f) (void) const;
} pmf_t;

初始化地图是可以的。问题是当我试图调用指向的函数时。我制作了一个再现问题的玩具示例。这是:

#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;
}

提前致谢, JIR

5 个答案:

答案 0 :(得分:5)

pmf_t类型的名称为f,因此第一个更改是删除*以获取second.f。这为您提供了指向成员的指针值。要使用指向成员的指针,您需要一个实例。您唯一可用的类型为this,因此请与->*运算符一起使用:

(this->*it->second.f)();

您需要围绕整个事项使用括号,否则编译器会认为您尝试调用it->second.f()(不允许),然后将结果应用于->*

答案 1 :(得分:3)

违规行试图在没有任何对象的情况下调用成员函数来调用它。如果打算为this对象调用它,我相信该调用应该看起来像

( this->* ((*it).second.f) )(); 

其中this->*是解除引用当前对象的成员指针的语法。 ((*it).second.f)是从地图中检索的指针,()是实际调用该函数的调用操作符。

这可能是一项很好的练习,但用途有限。

答案 2 :(得分:1)

我想你可能想查看一下C++ FAQ。正确的语法显然非常棘手(他们实际上建议使用宏)。

答案 3 :(得分:1)

试试这个:

(this->*((*it).second.f)) ();

答案 4 :(得分:1)

对于这个问题可能为时已晚,但看似复杂的语法可以分解为两个简单的行,所以看起来很清楚:

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
}