如何通过保存在容器中的成员指针函数调用?

Posted

技术标签:

【中文标题】如何通过保存在容器中的成员指针函数调用?【英文标题】:How to call through pointer-to-member function saved in a container? 【发布时间】:2019-11-11 22:44:47 【问题描述】:

我正在尝试编写一个成员函数,它依次调用同一对象的其他成员函数,直到其中一个起作用。

我想这样写:

class myClass

   bool A()  return false; 
   bool B()  return false; 
   bool C()  return false; 
   bool D()  return false; 
   void doIt() 
   
      const QList<bool (myClass::*) ()> funcs(
                      &myClass::A, &myClass::B, &myClass::C, &myClass::D
         );

      bool result(false);
      for (auto iter = funcs.cbegin(); !result && iter != funcs.cend(); ++iter) 
      
         result = this->(*iter) ();
      
   
;

但是我无法通过迭代器获得正确的语法来调用我的函数。 qt-creator 显示错误

called object type 'bool (myClass::*)()' is not a function or function pointer

指向第二个左括号,g++ 报告

must use .* or ->* to call pointer-to-member function

指向第二个右括号,都在我分配给DoIt成员函数的行中。 (请注意,g++ 错误消息中的示例运算符包含在重音符号中,但如果我包含它们,标记会删除“*”。)

我可以找到许多关于如何通过指向成员函数的指针进行调用的示例,但是对于将指向成员函数的指针保存在集合中并在 this 中调用的组合,却一无所获。

【问题讨论】:

this-&gt;*(*iter) () 工作吗? 没有。 QtCreator 和 g++ 都给出同样的错误。 另见isocpp.org/wiki/faq/pointers-to-members#macro-for-ptr-to-memfn 使用中间变量bool (myClass::*mfn) () = *iter;(或auto mfn = *iter)确实有助于使代码可读,然后通过简单的语法调用成员函数:(this-&gt;*mfn)(); 【参考方案1】:

由于()操作符的优先级绑定,需要多加一些括号:

result = (this->*(*iter))();

【讨论】:

太棒了!太感谢了。这种语法很奇怪,我不能自己解决它并不奇怪。 this-&gt;* *iter)() 就足够了。但是,为了更好的可读性,可以使用一个临时变量:auto mfn = *iter; (this-&gt;*mfn)()【参考方案2】:

除了 @1201ProgramAlarm 的答案之外,如果您可以访问 c++17 编译器,则可以通过使用来自 @987654324 的 std::invoke 来避免奇怪的语法@标头。

#include <functional> // std::invoke

result = std::invoke(*iter, this);

【讨论】:

也谢谢你;我期待着使用c++17 编译器。

以上是关于如何通过保存在容器中的成员指针函数调用?的主要内容,如果未能解决你的问题,请参考以下文章

this指针 (保存调用成员函数对象的地址)

通过VC++中的A类函数指针调用(B类的)类成员函数

如何从另一个成员函数调用成员函数指针?

c++类的成员函数指针如何转为普通指针

C++ this详解

如何从静态成员函数调用指向成员函数的指针?