为异构飞船运算符定义综合了哪些相等/比较运算符?

Hum*_*ler 5 c++ spaceship-operator c++20

C++20 引入了新的太空船运算符<=>,它允许根据三向比较的排序强度来合成相等和比较运算符。

然而,当使用以下简单的玩具示例执行异构比较时,它似乎无法合成相等运算符 - 但仍然成功合成排序运算符 - 尽管具有std::strong_ordering

#include <compare>
#include <cassert>

template <typename T>
struct Wrapper {
    int value;

    auto operator<=>(const Wrapper&) const = default;

    template <typename U>
    auto operator<=>(const Wrapper<U>& other) const {
        return value <=> other.value;
    }
};

void test() {
    // Same type equality -- works
    assert(Wrapper<Foo>{42} == Wrapper<Foo>{42});

    // Heterogeneous comparison -- works
    assert(Wrapper<Foo>{42} < Wrapper<Bar>{45});

    // Heterogeneous equality -- doesn't work?
    assert(Wrapper<Foo>{42} == Wrapper<Bar>{42});
}
Run Code Online (Sandbox Code Playgroud)

在 GCC 上,这会出现以下错误:

<source>: In function 'void test()':
<source>:26:29: error: no match for 'operator==' (operand types are 'Wrapper<Foo>' and 'Wrapper<Bar>')
   26 |     assert(Wrapper<Foo>{42} == Wrapper<Bar>{42});
      |            ~~~~~~~~~~~~~~~~ ^~ ~~~~~~~~~~~~~~~~
      |            |                   |
      |            Wrapper<Foo>        Wrapper<Bar>
Run Code Online (Sandbox Code Playgroud)

Live Example

据我从cppreference得知,强有序的自动合成运算符<=>应该包括相等性 - 但异构比较似乎并非如此,但它适用于同质比较。

这在gccclang、甚至 MSVC 上都会失败——所以我很确定这是正确的行为,尽管是意外的。operator== 我知道这也可以通过定义自定义来解决,但我的问题主要是为什么会发生这种情况,以及我期望从异构定义中生成什么operator<=>

归档时间:

查看次数:

831 次

最近记录:

5 年,1 月 前