C++20 引入了新的 spaceship 运算符<=>
,它允许基于三向比较的排序强度综合相等和比较运算符。
但是,似乎在使用以下执行异构比较的简单玩具示例时,它无法合成相等运算符 - 但仍然成功合成排序运算符 - 尽管有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});
}
在 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>
从我从cppreference可以看出,强序的自动合成运算符<=>
应该包括相等性——但是这似乎不是异类比较的情况,而是同质比较。
gcc
这在,甚至 MSVC 上都失败了clang
——所以我很确定这是正确的行为,尽管出乎意料。我知道这也可以通过定义自定义来解决operator==
,但我的问题主要是为什么首先会发生这种情况,以及我可以期望从异构operator<=>
定义中生成什么?