为什么我们不能在C ++中进行三向比较?

时间:2019-06-10 12:17:34

标签: c++

快速总结一下,为什么2 < x < 9不等于2 < x && x < 9

这是我编写的测试代码:

#include <iostream>

int main()
{
    int nums[] = { 5 , 1, 10};

    // We are gonna check if the number is in the range 2 - 9 
    for (auto e : nums)
    {
        if (2 < e < 9)
            std::cout << "2 < " << e << " < 9" << std::endl;

        if(2 < e && e < 9)
            std::cout << "2 < " << e << " and " << e << " < 9" << std::endl;
    }

    std::cin.get();
} 

这是我得到的输出:

2 < 5 < 9
2 < 5 and 5 < 9
2 < 1 < 9
2 < 10 < 9

似乎只有2 < e && e < 9可以正常工作。

6 个答案:

答案 0 :(得分:36)

表达式

2 < x < 9

分组为

(2 < x) < 9

并且由于2 < xfalse(0)或true(1),并且都小于9,因此始终为true

因此,除非您对非内置类型x使用重载运算符(否则,如果2 < x返回一个实例,则可以进行三向比较 定义了< proxy 对象),如果要测试x是否在时间间隔(2,9)中,则需要使用以下方式编写它:有。

答案 1 :(得分:20)

仅因为该语言没有该功能。

可以做到的,但这将与C以不兼容的方式形成对比。

可以制造C,但是设计师根本没有这么做。

您已经拥有正确的方法。

某些不同(和更新!)语言确实支持这一点。

答案 2 :(得分:4)

c ++中的比较运算符将两个值作为参数。 当您编写a<b时,它与operator<(a,b)相同。 并且operator <的返回值为bool。 当您在c ++中调用函数时,它正在计算其参数的表达式,然后将其传递给该函数,因此调用a<b<coperator<(operator<(a,b),c)

基本上,您的问题的答案是,在c ++中,没有比较运算符(小于,大于...)需要三个参数

答案 3 :(得分:3)

如果C ++选择重新定义a < b < c以更好地与数学符号保持一致,则它与当前含义将不明确。当前的含义有点愚蠢,正在将布尔值与数字进行比较,但是在生产使用中可能依赖于此细节的代码有些棘手。

由于C ++允许您使用运算符定义自己的类型,因此它也必须向您公开新的三元<,以便可以为您的类型创建一个。如果您只为类型定义二进制<而没有三元<,那么哪一种方法会打开新的蠕虫罐?编译器应该对您大喊大叫了吗?

答案 4 :(得分:3)

C ++不会这样做,因为那样会破坏与C的向后兼容性。因此,您需要再追溯十年才能找到答案。

我不知道Brian Kernighan或Dennis Ritchie是否曾经考虑过采用其他方式,或讨论过他们的推理。我不知道有人要求该特定功能。他们的关系运算符遵循与其他Algol族语言相同的规则。

一个问题是它会使语法变得模棱两可:0 < x < 1现在的含义与(0 < x) < 10 < (x < 1)完全不同。还有如何解析a < b >= ca < b == c的问题。请记住,K&R C中没有布尔类型。逻辑运算符返回int,因为假定结果存储在机器寄存器中。

其背后的另一个可能原因是,根据其设计师的说法,K&R C不是一种高级语言。它的基本操作通常与所开发的小型计算机上的机器指令相对应。因此,当时的比较只是机器指令,而不是双重比较。考虑到他们做出的其他选择,将特殊的语法糖引入语言中只是为了使C代码读起来更像数学论文,这真是奇怪。

答案 5 :(得分:1)

if 内,应该有布尔条件。在2 中,有两个条件。在C ++中,如果没有两个运算符,则无法计算两个条件。这就是为什么我们不能使用 2 的原因。