编译器以不同的方式对待下列代码:
#include <compare>
struct A;
struct I {
virtual std::strong_ordering operator <=>(const A&) const {
return std::strong_ordering::equal;
}
};
struct A : I {
virtual std::strong_ordering operator <=>(const A&) const = default;
};GCC和MSVC都接受它,但不接受返回错误的Clang:
warning: explicitly defaulted three-way comparison operator is implicitly deleted [-Wdefaulted-function-deleted]
virtual std::strong_ordering operator <=>(const A&) const = default;
defaulted 'operator<=>' is implicitly deleted because there is no viable three-way comparison function for base class 'I'
error: deleted function 'operator<=>' cannot override a non-deleted function
virtual std::strong_ordering operator <=>(const A&) const = default;演示:https://gcc.godbolt.org/z/WGrGTe89z
看来Clang是这里唯一的一个,因为I::operator <=>(const I&) const没有定义,所以必须隐式删除A::operator <=>(const A&) const,并且已删除的方法不能覆盖I中未删除的方法。其他编译器是否也有权接受代码?
发布于 2021-12-13 21:23:07
当您编写类似于A a; a < a;的代码时,其他编译器也会拒绝它,这使我认为Clang过早地拒绝了它。在[class.compare.default]中,标准是:
C类的比较运算符函数在第一次声明时默认,但未被定义为已删除,在odr使用或常量计算所需时,将隐式定义它。比较运算符函数的默认定义中的名称查找是从与其函数体等效的上下文中执行的。类中出现的默认比较运算符的定义应是该函数的第一次声明。
由于在您的示例中没有解析到A::operator<=>(const A&)的表达式,所以不需要定义,也不应该拒绝它,即使函数最终总是被删除。
https://stackoverflow.com/questions/70334766
复制相似问题