为什么我可以使用默认的 <=> 而不是用户提供的来调用 ==?

xml*_*lmx 7 c++ comparison standards spaceship-operator c++20

#include <compare>

struct A
{
    int n;
    auto operator <=>(const A&) const noexcept = default;
};

struct B
{
    int n;
    auto operator <=>(const B& rhs) const noexcept
    {
        return n <=> rhs.n;
    }
};

int main()
{
    A{} == A{}; // ok
    B{} == B{}; // error: invalid operands to binary expression
}
Run Code Online (Sandbox Code Playgroud)

用 clang-10 编译为 clang -std=c++20 -stdlib=libc++ main.cpp

为什么A{} == A{}有效但无效B{} == B{}

L. *_* F. 9

在飞船运营商的最初设计中,==允许调用<=>,但后来由于效率问题而被禁止(<=>通常是一种低效的实现方式==)。 operator<=>() = default仍然定义为隐式定义,为方便起见operator==,它正确调用==而不是<=>成员。所以你想要的是这个:

struct A {
    int n;
    auto operator<=>(const A& rhs) const noexcept = default;
};

// ^^^ basically expands to vvv

struct B {
    int n;
    bool operator==(const B& rhs) const noexcept
    {
        return n == rhs.n;
    }
    auto operator<=>(const B& rhs) const noexcept
    {
        return n <=> rhs.n;
    }
};
Run Code Online (Sandbox Code Playgroud)

请注意,您可以独立默认,operator==同时仍提供用户定义的operator<=>

struct B {
    int n;
    // note: return type for defaulted equality comparison operator
    //       must be 'bool', not 'auto'
    bool operator==(const B& rhs) const noexcept = default;
    auto operator<=>(const B& rhs) const noexcept
    {
        return n <=> rhs.n;
    }
};
Run Code Online (Sandbox Code Playgroud)