C ++ 20中有一个新的比较运算符<=>
。但是我认为在大多数情况下,简单的减法效果很好:
int my_strcmp(const char *a, const char *b) {
while (*a == *b && *a != 0 && *b != 0) {
a++, b++;
}
// Version 1
return *a - *b;
// Version 2
return *a <=> *b;
// Version 3
return ((*a > *b) - (*a < *b));
}
它们具有相同的效果。我无法理解其中的差异。
答案 0 :(得分:50)
运算符解决了减法带来的数字溢出问题:如果从接近INT_MIN
的负数中减去一个大的正数,则得到的数字不能表示为{{1因此导致未定义的行为。
虽然版本3没有这个问题,但它完全缺乏可读性:以前从未见过这个技巧的人需要花一些时间才能理解。 int
运算符也修复了可读性问题。
这只是新运营商解决的一个问题。 Herb Sutter's Consistent comparison paper的第2.2.3节讨论了<=>
与其他数据类型的使用,其中减法可能会产生不一致的结果。
答案 1 :(得分:40)
以下是一些减法不适用的案例:
unsigned
种类。operator -
的用户定义类型(可能因为它没有意义 - 可以定义订单而不定义距离概念)。我怀疑这份清单并非详尽无遗。
当然,至少可以为#1和#2提供变通方法。但operator <=>
的意图是封装丑陋。
答案 2 :(得分:15)
这里有一些有意义的答案,但his paper中的Herb Sutter特别说:
&LT; =&GT;用于类型实现者:在运算符&lt; =&gt;的实现之外的用户代码(包括通用代码)应该几乎不会调用&lt; =&gt;直接(已经被发现作为其他语言的良好做法);
所以即使没有区别,运算符的要点也不同:帮助类编写者生成比较运算符。
减法运算符和“太空船”运算符之间的核心差异(根据Sutter的提议)是重载operator-
为您提供减法运算符,而重载operator<=>
:
default
:无需编写代码!); 其他差异在于返回值:operator<=>
将返回类的enum
,该类指定类型是否可排序以及排序是强还是弱。返回值将转换为-1,0或1(尽管Sutter为返回类型留出空间以指示距离,如strcmp
所做的那样)。在任何情况下,假设-1,0,1返回值,我们终于得到a true signum function in C++! (signum(x) == x<=>0
)