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

Why can I invoke == with a defaulted <=> but not a user-provided one?

#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
}

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

为什么 A{} == A{} 有效而 B{} == B{} 无效?

飞船操作符最初的设计中,允许==调用<=>,但后来出于效率考虑不允许这样做(<=>通常是一种低效的方式实施 ==)。 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;
    }
};

请注意,您可以独立地默认 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;
    }
};