当前位置: 首页 > 知识库问答 >
问题:

三元比较算子与减法有何不同?

单于帅
2023-03-14

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));
}

它们的效果是一样的。我真的不明白这有什么区别。

共有3个答案

养学
2023-03-14

关于这种差异,这里有一些有意义的答案,但Herb Sutter在他的论文中特别指出:

<=>是针对类型实现者的:运算符<=>实现之外的用户代码(包括泛型代码)几乎永远不应该直接调用<=>(这在其他语言中已经发现了一个好的实践);

因此,即使没有区别,运算符的意义也是不同的:帮助类编写器生成比较运算符。

减法运算符和“宇宙飞船”运算符之间的核心区别(根据Sutter的提议)是,重载运算符-给你一个减法运算符,而重载运算符<=>:

  • 提供6个核心比较运算符(即使您将运算符声明为default:no code to write!);
  • 声明您的类是可比较的,是可排序的,以及顺序是总的还是部分的(在Sutter的建议中是强的/弱的);
  • 允许异类比较:您可以重载它以将您的类与任何其他类型进行比较。

其他区别在于返回值:运算符<=>将返回类的枚举,类指定类型是否可排序以及排序是强还是弱。返回值将转换为-1、0或1(不过Sutter为返回类型也指示距离留出了空间,就像strcmp所做的那样)。无论如何,假设返回值为-1,0,1,我们最终将在C++中得到一个真正的信号函数!(符号(x)==x<=>0)

宫俊远
2023-03-14

以下是一些减法不起作用的情况:

  1. 无符号类型。
  2. 导致整数溢出的操作数。
  3. 不定义运算符-用户定义类型(可能是因为它没有意义-可以定义顺序而不定义距离的概念)。

我怀疑这份清单并非详尽无遗。

当然,至少可以为#1和#2找到变通方法。但是operator<=>的意图是封装这种丑陋。

凌鹏程
2023-03-14

该运算符解决了用减法得到的数字溢出问题:如果从接近int_min的负数中减去一个大的正数,则会得到一个不能表示为int的数字,从而导致未定义的行为。

虽然版本3没有这个问题,但它完全缺乏可读性:以前从未见过这个技巧的人需要一些时间才能理解。<=>运算符也修复了可读性问题。

这只是新运营商解决的一个问题。Herb Sutter的一致比较论文的2.2.3节谈到了在减法可能产生不一致结果的语言的其他数据类型中使用<=>

 类似资料:
  • Herb Sutter在他关于“宇宙飞船”操作员的建议(第12页底部第2.2.2节)中说: 基于及其返回类型:该模型具有主要优点,与以前针对C++的建议和其他语言的功能相比,该建议具有一些独特之处: [...] (6)效率,包括最终实现对比较的零开销抽象:绝大多数的比较总是单程通过的。唯一的例外情况是在同时支持偏序和相等的类型的情况下生成和。对于,单次传递对于实现零开销原则以避免重复相等比较至关重

  • 考虑以下两个用于的重载: 如果我将对象与进行比较,将为我生成正确的运算符,所以像、

  • 有没有可能改变这一点: 到三元运算符?

  • HPB是一套基于特定硬件设备的高性能区块链基础设施。其运行在分布式的网络上——各个节点通过P2P的邻居节点相连,各类节点之间独立维护自己各自的区块。HPB的共识算法为系统的核心,共识算法负责协调各类节点以保障整个系统的交易和智能合约的数据一致性。 HPB的算法是一种基于委托投票的POA提升算法。 Proof of Authority [1] 是运行可信区块链节点上的一种共识算法,其更轻量的消息交换

  • 我必须将元组与元组列表进行比较,如果整数小于列表中的任何元组,则返回True。例如,如果我有将返回True,因为单独元组(“番茄”,10,5)中的整数比列表中的元组(“橙色”,11,6)小,但是如果我有将返回False。 我试试这个 但不工作时,它应该返回假,我不知道为什么? 注意:字符串对于这个问题并不重要,我必须忽略它。

  • 问题内容: 我发现该方法的实现如下所示: 问题是为什么使用比较而不是减法: 问题答案: 这是由于整数溢出。当非常大且为负数时,则从前者中减去后者会产生大于可能溢出至负数范围的结果。