【问题标题】:Why can I invoke == with a defaulted <=> but not a user-provided one?为什么我可以使用默认的 <=> 而不是用户提供的调用 ==?
【发布时间】:2020-07-17 06:38:03
【问题描述】:
#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{} 无效?

【问题讨论】:

    标签: c++ comparison standards c++20 spaceship-operator


    【解决方案1】:

    在 spaceship 算子的原始设计中,== 可以调用&lt;=&gt;,但后来出于效率考虑不允许这样做(&lt;=&gt; 通常是实现== 的低效方式)。 operator&lt;=&gt;() = default 仍被定义为隐式定义 operator==,为方便起见,它正确调用成员上的 == 而不是 &lt;=&gt;。所以你想要的是这样的:

    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&lt;=&gt;

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

    【讨论】:

    • @xmllmx [over.match.oper]/3.4(注意==的重写候选集不包括&lt;=&gt;
    • operator() = default 仍然被定义为隐式定义 operator==,你能不能把这个声明上的标准页面给我?
    猜你喜欢
    • 2018-11-10
    • 1970-01-01
    • 2018-07-09
    • 1970-01-01
    • 2012-04-12
    • 2010-12-13
    • 2015-04-12
    • 1970-01-01
    • 2019-11-08
    相关资源
    最近更新 更多