2

编译器对以下代码的处理方式不同:

#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。其他编译器是否也有权接受代码?

4

1 回答 1

1

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

类 C 的比较运算符函数在其第一个声明中默认并且未定义为已删除,当它被使用或需要用于常量评估时,它会被隐式定义。比较运算符函数的默认定义中的名称查找是从与其函数体等效的上下文中执行的。出现在类中的默认比较运算符的定义应是该函数的第一个声明。

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

于 2021-12-13T21:23:07.877 回答