指向虚拟成员函数的指针是不是具有可比性?

Posted

技术标签:

【中文标题】指向虚拟成员函数的指针是不是具有可比性?【英文标题】:Are pointers to virtual member functions comparable?指向虚拟成员函数的指针是否具有可比性? 【发布时间】:2015-04-05 09:11:33 【问题描述】:

我读到an article 说

成员函数指针可以设置为0,并提供操作符 == 和 !=,但仅适用于同一类的成员函数指针。

我正在尝试理解 C++11,§5.10。

§5.10/1 中说

可以比较相同类型的指针(指针转换后) 为了平等。

§5.10/2 中说

否则,如果其中一个是指向虚成员函数的指针,则 结果未指定。

现在考虑以下测试程序。

#include <cassert>

class ISomeClass

public:
   virtual ~ISomeClass() 

   virtual void a() = 0;
   virtual void b() = 0;
;

int main()

   typedef void(ISomeClass::*MemberPtr)();

   MemberPtr mp = &ISomeClass::a;

   assert( mp == &ISomeClass::a );
   assert( mp != &ISomeClass::b );

   return 0;

根据标准,断言是真实的还是未指定的?

【问题讨论】:

它们是“相同类型的指针”,所以 /1 适用,而不是 /2(“否则”)。 指向成员的指针不是标准用语中的指针(参见 [dcl.mptr]/3)。 /2 适用,但 /2 在这个特殊的“否则”之前有很多内容。 “如果两个操作数都为空,则它们比较相等。否则,如果只有一个为空,则它们比较不相等。否则,如果其中一个是指向虚拟成员函数的指针,则结果未指定。”它说,前面是对用于将操作数变为相同类型的转换的描述。在我看来,它没有具体说明。 我的英语在这里失败了。 “任何一个”是指:任何个指针,还是:不是两个指针?含义很重要,因为标准中的内容是“否则,当且仅当它们引用同一个最衍生对象的同一个成员时,它们比较相等”,这意味着我的示例程序将遵循标准。 我发现 Herb Sutter 的 an article 说“......因为标准直接支持所有指针类型的指针相等比较,包括所有函数指针类型。” 在a coding standard page 中,他们得出的结论是它未指定 【参考方案1】:

我认为一般的指向成员的指针是对对象地址的转移。对于指向虚拟方法的指针,我认为细节取决于实现。在一般情况下,我认为这样做是个坏主意,但是如果在分配期间将指针解析为正确的覆盖,它必须作为指向成员函数的标准指针,并且比较是移位比较加方法签名比较。检查 reinterpret_cast 到 long 看看会发生什么。

【讨论】:

感谢您的意见!请注意,我们只比较同一个纯虚拟接口中的成员函数指针。 IE。我们不会将接口中的成员函数指针与子类中的覆盖成员函数指针进行比较。 结果取决于编译器。它可以检查这个表达式是否错误并拒绝编译它。但是,如果您可以编译它,则比较必须以预期的方式产生(断言 2 失败)。恕我直言。 是的,但不幸的是这不是便携式的。甚至在同一编译器的不同版本之间也不行。

以上是关于指向虚拟成员函数的指针是不是具有可比性?的主要内容,如果未能解决你的问题,请参考以下文章

C++ 指向具有匹配函数签名的任何类的成员函数的指针

指向具有私有构造函数的类的类成员的指针

C++|详解类成员指针:数据成员指针和成员函数指针及应用场合

具有指向成员函数的指针的 SFINAE 类型特征失败

指向不同类的成员函数的指针

指向实例的成员函数而不是类的指针