奇怪的条件格式

Weird conditional format

本文关键字:格式 条件      更新时间:2023-10-16

在我无尽的旅程中,在这个美丽的东西,也被称为The Internet的巨大而危险的平面上,我遇到了一个神秘的、老的、白胡子的巫师,他的名字不能提。尽管他非常强大,但死亡很快就把他带走了。

临终前他递给我一卷书,昏倒时低声说

Take this and spread the knowledge

在他死后,他的身体迅速转化为能量,纯净的能量在宇宙中传播。

卷轴包含这段代码:

#include <iostream>
int main()
{
    int x = 3;
    while(2 <= x <= 5)
        std::cout << x++;
}

这个谜直到今天仍然存在:

条件如何求值?

总是为true,因为2<=x要么计算为1要么计算为0,两者都是<=5

这实际上是一个无限循环:

while( (2 <= x) <= 5)
    std::cout<<x++;

这个卷轴的作者想要表达一个条件,我们称之为链式运算符符号,这在数学中是众所周知的(也许向导是个数学家?):

Let x ∈ ℜ, 2 ≤ x ≤ 5. Then ...

通常,这在c++、C、Java和许多其他具有类似表达式求值逻辑的语言中是不可能的。有一些库支持这样的特性,但另一方面引入了冗长,因为您必须首先包装一个参数。而且,对于程序员来说,它不是很好读。

如果您使用向导在此卷轴上所使用的语言编写表达式,则将从左到右对进行计算:

while ( (2 <= x) <= 5 )
    ...

总是true,因为2 <= x要么是true,要么是false,并且分别隐式转换为10的整型值,这两个值总是小于或等于5

要按照数学家的要求来表达条件,必须使用语法

while ( (2 <= x) && (x <= 5) )
    ...

或者使用一个实用函数来精确地表达:

template<class T>
bool between(const T& arg, const T& min, const T& max) {
    return !(arg < min) && !(max < arg);
}

while ( between(x, 2, 5) )
    ...

请注意我是如何在between中编写条件的:它只需要实现operator<(T, T),从而简化了自定义类型的实现。