问题是如何乘坐火箭起飞:)
我说的是运营商<=>。起初在我看来,这将是一些简单的事情,比如strcmp- 返回小于、大于或等于。
第一个令人失望的是,它们会返回某种“左”类型,您甚至不会直接在if. 我决定我真的不需要他,他太奇怪了。
但是最近我遇到了一个注释,如果你只为你的类型定义它,那么你不需要编写一个比较运算符。例如,我开始寻找并阅读有关他的信息-但很明显他喝了一点:(没有添加清晰度。
如果我理解正确,有人可以帮助我理解通过定义一个运算符<=>,我会自动获得所有关系运算符吗?
以及如何正确定义它?
作为奖励:) - 为什么这么复杂?不只是,比如说,返回-1、0、+1?
好吧,或者告诉我在哪里有关于这个主题的一些咀嚼材料,最好是俄语。
<=>通常不需要手动呼叫。但如果你真的想要,那么它的结果可以与零进行比较,大致类似于 的结果strcmp。示例:(a <=> b) < 0表示a < b(括号可以省略)。关于它的返回类型如下。如果你
<=>通过编写重载= default,那么所有 6 个运算符都会自动工作:==,!=,<,<=,>,>=. 将比较所有字段。= default您只能在类主体中重载 with 。选择:如果手动超载
<=>,则只有 4 个可以工作:<,<=,>,>=. 您==需要单独重新加载,然后它!=会自动开始工作(不管<=>)。without
= default可以在类内部和外部重载。最简单的方法是作弊,这样写:
并且最好以
tie不写4次的方法取出。重要的是不要屈服于诱惑而没有
operator==实现a <=> b == 0。一般来说,这会比使用==. (例如,要通过 比较两个字符串<=>,需要遍历字符。或者==您可以先比较大小,如果它们不同,则不执行其他操作。)operator==在 C++20 中,您还可以重载为= default. 它将比较所有字段是否相等,a <=> b == 0即使您重载了也不会使用<=>。如果你想
<=>手写而不用tie,那么你需要选择返回类型。在下一个答案中,他们建议int,它甚至似乎有效,但不知何故令人怀疑。有三个标准类可供选择,它们的行为大致类似于枚举:std::strong_ordering- 更大/更少/等于std::weak_ordering- 大于/小于/等价 - 基本相同,但表示不同的对象可以被认为是等价的。一个例子是不区分大小写的字符串比较。std::partial_ordering- 大于/小于/等价/不可比较 - 与 相同weak_ordering,但添加了第四个值“不可比较”,这会导致所有 6 个运算符返回 false。示例:NaN与任何其他数字“无法比较”,对其自身也是如此。所有三个都可以与零进行比较:
x < 0均值x == ...::less等。还有
<compare>各种方便编写的小工具<=>,例如std::common_comparison_category,它为被比较的对象类型选择适当的返回类型。<=>可用于比较不同类型的对象。显然= default,在这种情况下它不会有帮助。编译器知道操作数的顺序并不重要,所以重载就足够了
A <=> B,B <=> A它会自己工作,所有 4 个运算符也可以处理任何参数的顺序。同样,如果您重载
A == B,它将B == A自行工作,并且也!=可以使用任何顺序的参数。详细信息:实际上没有其他语句生成
<=>.==相反,当您尝试调用另一个运算符时,编译器会将其替换为 call<=>or==,可能会更改参数的顺序。不同之处在于,例如,您不能获取这样一个不存在的运算符 (a la
&MyClass::operator<) 的地址,并且可能还有其他东西。作为一个实际的人:),我将给出一个重新定义运算符的实际示例。
如果您对按字段进行比较(例如在元组中)感兴趣,那么在类中(为了确定性
Test)编写就足够了如果你想要一些奇怪的东西,那么你需要定义这个 operator 和 operator
==。例如,这是这样一个类和比较,其中偶数小于奇数。
在 VC++2019 输出中
好吧,你可以在程序中使用火箭,例如,像这样:
PS 同时,没有人打扰您定义自己的关系运算符,在这种情况下,当然会使用它们,而不是生成的。
PPS 编程是一门实验科学 :),所以请尝试深入研究代码...