被隐式删除的函数覆盖已删除虚函数:哪种编译器实现正确?
这是一个关于C++标准在特定场景下的解读问题,示例代码如下:
struct B; struct A { virtual bool operator ==(const B&) const = delete; }; struct B : A { bool operator ==(const B&) const = default; };
不同编译器对这段代码的处理存在差异:
- GCC、EDG、MSVC均拒绝编译,报错信息为:
error: nondeleted function overrides deleted function "A::operator=="
根据cppreference中的规则,这个报错看似合理:
A deleted function can only be overridden by deleted functions
但Clang接受了该程序,并给出提示信息:
note: defaulted 'operator==' is implicitly deleted because there is no viable 'operator==' for base class 'A'
问题
请问上述哪种编译器实现符合C++标准?
分析与结论
根据C++标准,当用=default声明的默认函数无法生成合法定义时,会被隐式删除。在这个场景中,B类的operator==被声明为默认函数,但基类A中对应的虚函数operator==(const B&)是被删除的,默认生成的B的operator==无法调用基类版本完成完整比较逻辑,因此该函数会被隐式删除。
标准中规定“被删除函数只能被被删除函数重写”,而B中的operator==本质上是被隐式删除的函数,因此它重写基类中被删除的operator==是完全合法的。
综上,Clang的实现符合C++标准,而GCC、EDG、MSVC错误地将=default声明的函数直接判定为“非删除函数”,未考虑其会被隐式删除的情况,因此它们的报错不符合标准要求。
内容的提问来源于stack exchange,提问作者Fedor

