

如果知道我会死在哪里,那我将永远不去那个地方 -查理 芒格
上一章节我们说到三路比较运算符,本章作为其姊妹篇继续补充其相关知识。
默认<=>
运算符<=>默认函数通过依次比较自定义数据类型的父类(从左到右深度优先)和自己的非静态成员对象来执行字典顺序比较,以计算判定<=>的结果,同时会递归地比较数组成员(按下标递增的顺序),并在发现不相等的结果时提前停止。同时,是否对于虚基类的子对象的比较是不确定的。
返回值类别
如果重载操作符<=>函数的返回值为auto,实际返回类型是要比较的基类和自己的成员对象和成员数组元素的通用比较类别。
template <class... _Types>
using common_comparison_category_t =
conditional_t<(_Classify_category<_Types...> & _Comparison_category_none) != 0, void,
conditional_t<(_Classify_category<_Types...> & _Comparison_category_partial) != 0, partial_ordering,
conditional_t<(_Classify_category<_Types...> & _Comparison_category_weak) != 0, weak_ordering,
strong_ordering>>>;有上式可知,其返回类型存在四种情况:void、partial_ordering、weak_ordering、strong_ordering。
由以上可知,三路比较运算符的返回结果并不是数值,而是预定义的枚
enum class _Compare_eq : _Compare_t { equal = 0, equivalent = equal };
enum class _Compare_ord : _Compare_t { less = -1, greater = 1 };
enum class _Compare_ncmp : _Compare_t { unordered = -128 };根据任何运算符<=>重载的规则,一个<=>的默认重载还将允许将类型与<、<=、 >=、> 进行比较。如果 operator<=> 是默认值,并且根本没有声明 operator==,则 operator== 是隐式默认值。
自定义<=>
当默认语义的<=>不满足需求时,程序员可以自定义<=>。其返回值类型可以有三种,强序、弱序、部分顺序,如何确定应该使用哪种返回值呢?
默认==比较
返回bool型的默认==运算符重载将会基于声明顺序对基类和成员变量依次进行==比较,所有值均相等则相等,遇到非相等值立即返回。
重载==的数据类型也支持进行!=。
struct Point
{
int x;
int y;
bool operator==(const Point&p) const =default;
// ... non-comparison functions ...
};
// compiler generates element-wise equality testing
void using_default_equal()
{
Point pt1{ 3, 5 }, pt2{ 2, 5 };
std::cout << std::boolalpha
<< (pt1 != pt2) << '\n' // true
<< (pt1 == pt1) << '\n'; // true
}其他默认比较操作运算符
四个关系运算符(<,>,<=,>=)均可以显式指定为预置。预置的关系运算符必须返回 bool。
如果 x <=> y 的重载决议失败,或operator@(<,>,<=,>=)无法被应用到 x <=> y 的结果,则这种操作符(<,>,<=,>=)被废弃(deleted)