首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当父类未为自身定义宇宙飞船运算符时重写宇宙飞船运算符

当父类未为自身定义宇宙飞船运算符时重写宇宙飞船运算符
EN

Stack Overflow用户
提问于 2021-12-13 12:34:47
回答 1查看 272关注 0票数 3

编译器以不同的方式对待下列代码:

代码语言:javascript
复制
#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:

代码语言:javascript
复制
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中未删除的方法。其他编译器是否也有权接受代码?

EN

回答 1

Stack Overflow用户

发布于 2021-12-13 21:23:07

当您编写类似于A a; a < a;的代码时,其他编译器也会拒绝它,这使我认为Clang过早地拒绝了它。在[class.compare.default]中,标准是:

C类的比较运算符函数在第一次声明时默认,但未被定义为已删除,在odr使用或常量计算所需时,将隐式定义它。比较运算符函数的默认定义中的名称查找是从与其函数体等效的上下文中执行的。类中出现的默认比较运算符的定义应是该函数的第一次声明。

由于在您的示例中没有解析到A::operator<=>(const A&)的表达式,所以不需要定义,也不应该拒绝它,即使函数最终总是被删除。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70334766

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档