根据评论,这个版本的clang及其标准库似乎:
-
确实实现了的语言功能
<=>
但是
-
尚未实现的库添加
<=>
(特别添加
<=>
对于
std::string
)。
当你写作时:
struct MyStruct
{
float a{};
int b{};
std::string c{};
MyEnum d{};
auto operator<=>(const MyStruct&) const = default;
};
什么违约
<=>
方法是使用
<=>
,返回比较不相等的第一个成员的值。当您使用
auto
,即要求编译器为您推导比较类别,但与的典型用法不同
汽车
(其中所有返回类型必须相同,以及
汽车
推导到那一种类型),这里我们取所有比较类别的最小值。例如,如果我们有一个成员
<=>
返回
weak_ordering
但另一个
<=>
返回
strong_ordering
,a默认
<=>
会回来的
弱排序
(而不是不编译)。基本上,它按照你期望的方式,做你可能希望它做的事情。
但是——有时违约
<=>
如果你的一个成员实际上没有提供
<=>
然而
(在这种情况下)。在这种情况下,必须手动写出所有的比较结果会很乏味。因此,有另一种方法可以默认
<=>
(来自
P1186
):您可以显式提供比较类别:
struct MyStruct
{
float a{};
int b{};
std::string c{};
MyEnum d{};
std::strong_ordering operator<=>(const MyStruct&) const = default;
};
这意味着,而不是简单地做会员
<=>
,我们做了一些更为复杂的事情:
-
如果该成员
<=>
,使用它。并且它必须满足比较类别的要求(在这种情况下,它将碰巧失败,因为
float
s与相比
partial_ordering
,不符合
strong订单
要求-因此必须返回
部分排序
)。
-
如果成员
没有
提供
<=>
,我们从
==
和
<
。
因此,在这种情况下:
struct MyStruct
{
float a{};
int b{};
std::string c{};
MyEnum d{};
std::partial_ordering operator<=>(const MyStruct&) const = default;
};
会表现得像:
std::partial_ordering operator<=>(const MyStruct& rhs) const {
// a and b provide <=>, so use it
if (auto cmp = a <=> rhs.a; cmp != 0) return cmp;
if (auto cmp = b <=> rhs.b; cmp != 0) return cmp;
// c doesn't yet, so synthesize one
if (auto cmp =
(c == rhs.c ? partial_ordering::equivalent :
c < rhs.c ? partial_ordering::less :
c > rhs.c ? partial_ordering::greater :
partial_ordering::unordered); cmp != 0) return cmp;
// and d does, so use it
return d <=> rhs.d;
}
这个语言功能的优点(正如我在那篇论文中所阐述的)是
std::字符串
确实提供
<=>
,您的实现将自动获取它,并且效率更高(因为上面的实现对于字符串来说真的不是一个好的实现,您希望这样做
c.compare(rhs.c) <=> 0
),而不用你自己做所有的工作。