指向虚成员函数的指针可以进行比较吗?

4
我读了一篇文章,其中提到
成员函数指针可以设置为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(“否则”)。 - Konrad Rudolph
2
成员指针在标准用语中并不是指针(参见[dcl.mptr]/3)。/2适用,但在这个特定的“否则”之前,/2中有很多内容。它说:“如果两个操作数都为null,则它们相等。否则,如果只有一个为null,则它们不相等。否则,如果任一操作数是虚拟成员函数的指针,则结果是未指定的。” 这是在描述将操作数转换为相同类型所应用的转换之前。对我来说看起来是未指定的。 - Wintermute
我的英语在这里有些力不从心。 “either” 是指:任何一个指针,还是不是两个指针都不是?意义至关重要,因为标准中接下来的内容是“否则,只有当它们将引用同一最派生对象的同一成员时,它们才会相等地比较”,这意味着我的示例程序将遵循标准。 - Daniel
我发现Herb Sutter的一篇文章,其中提到:“...因为标准直接支持所有指针类型(包括所有函数指针类型)的指针相等比较。” - Daniel
在一份编程规范页面中,他们得出了结论,这是未指定的 - Daniel
一份有关虚拟成员函数指针比较的提案已经提交给标准化委员会。 - Daniel
1个回答

1

我认为普通的成员指针是在对象地址上进行移位。对于指向虚拟方法的指针,我认为细节取决于实现。一般情况下,我认为这样做是不好的想法,但如果指针在赋值期间解析为正确的重载,则必须像标准成员函数指针一样工作,并且比较是移位比较加上方法签名比较。请检查reinterpret_cast到长整型以查看发生了什么。


感谢您的输入!请注意,我们仅在同一纯虚拟接口内比较成员函数指针。也就是说,我们不会将接口中的成员函数指针与子类中覆盖的成员函数指针进行比较。 - Daniel
结果取决于编译器。它可以将此表达式视为错误并拒绝编译。但是,如果您可以编译它,则比较必须以预期的方式产生结果(assert 2失败)。在我看来。 - Mel Viso Martinez
是的,但不幸的是这并不具有可移植性。甚至在同一编译器的不同版本之间也不行。 - Daniel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接