从结构体中调用成员函数指针所指向的函数

发布于 2024-11-26 21:00:39 字数 900 浏览 3 评论 0原文

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

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

地图初始化就OK了。问题是当我尝试调用指向的函数时。我编了一个重现问题的玩具示例。在这里:

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

提前致谢, 吉尔

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

⒈起吃苦の倖褔 2024-12-03 21:00:39

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

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

您需要用括号将整个内容括起来,否则编译器将认为您正在尝试调用 it->second.f() (这是不允许的),然后将结果应用于 ->*

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 ->*.

扬花落满肩 2024-12-03 21:00:39

有问题的行试图调用一个没有任何对象来调用它的成员函数。如果目的是为 this 对象调用它,我相信调用应该类似于

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

其中 this->* 是取消引用指向成员的指针的语法对于当前对象。 ((*it).second.f) 是从映射中检索的指针,() 是实际调用该函数的调用运算符。

这也许作为一种练习很好,但在其他方面用途有限。

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.

傲影 2024-12-03 21:00:39

我想您可能想查看 C++ 常见问题解答 关于这一点。语法显然很难正确使用(他们实际上建议使用宏)。

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

天荒地未老 2024-12-03 21:00:39

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

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
}

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
}
不可一世的女人 2024-12-03 21:00:39

试试这个:

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

try this:

(this->*((*it).second.f)) ();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文