c++ - 当父类没有为自己定义宇宙飞船运算符时覆盖宇宙飞船运算符

标签 c++ overriding language-lawyer spaceship-operator

以下代码被编译器区别对待:

#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 中未删除的方法.其他编译器是否也有权接受代码?

最佳答案

一旦您编写类似 A a; a < a; 的代码,其他编译器也会拒绝该代码,这让我觉得 Clang 过早地拒绝了它。在 [class.compare.default] ,标准说:

A comparison operator function for class C that is defaulted on its first declaration and is not defined as deleted is implicitly defined when it is odr-used or needed for constant evaluation. Name lookups in the defaulted definition of a comparison operator function are performed from a context equivalent to its function-body. A definition of a comparison operator as defaulted that appears in a class shall be the first declaration of that function.

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

关于c++ - 当父类没有为自己定义宇宙飞船运算符时覆盖宇宙飞船运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70334766/

相关文章:

c++ - 重新声明模板参数

C++ - 指针函数参数

c - 如何覆盖 C 库中的 fprintf?如何将 GCC 选项添加到顶级 CMakeLists.txt?

c# - 如果派生类没有覆盖方法,应该调用哪个版本?

c++ - 为什么我的重载 << 不返回任何数据?

c++ - C++中两个线程的互斥量

swift - 无法覆盖 prefersHomeIndicatorAutoHidden() 方法

c - 可变长度数组的 sizeof 计算

c++ - 通用 lambda 的熟悉模板语法

c++ - 我可以为 C++ 中的条件表达式赋值吗?