为什么使用“==”比较三个变量时会得到false的结果?

3
以下程序的输出结果是“they are not equal”,但我期望的结果是“they are equal”,因为三个比较的变量(xyz)是相等的。为什么会这样呢?
#include <iostream>

int main()
{
    int y, x, z;
    y = 3;
    x = 3;
    z = 3;

    if (x == y == z)
    {
        std::cout << "they are equal\n";
    }
    else
    {
        std::cout << "they are not equal\n";
    }
}

1
相关/重复:https://dev59.com/omoy5IYBdhLWcg3wFqJT - NathanOliver
if (x == y == z) 不会做你想要的事情。 - drescherjm
所以我不能在一行中等价于3个数字,而不是分别等价于每2个数字吗? - Snake Eyez
你是对的,你不能在一行中等价于3个数字,而不是分别等价于每2个数字。 - drescherjm
3
正确。因为比较会得出一个布尔值,然后你将其与一个数字进行比较。 - RL-S
2个回答

10
这是因为表达式和类型的计算方式不同。让我们计算最左边的==
x == y ...

这个表达式的值为true。让我们重写一下表达式:

//  x == y
if (true   == z) {
    // ...
}

true是布尔值,不能直接与int进行比较。必须将布尔值转换为整数,结果为1(是的,true == 1)。让我们将表达式重写为其等价值:

//  true
if (1    == z) {
    //    ^--- that's false
}

但是z不等于1。这个表达式是错误的!

相反,你应该分开两个布尔表达式:

if (x == y && y == z) {
    // ...
}

0

下面是一些实际的C++17应用。不需要SFINAE。

//----------------------------------
// constexpr lambda requires C++17
auto eq3 = [] (auto v1, auto v2, auto v3) constexpr -> bool
{
    return ( v1 == v2 ) && ( v2 == v3 );
};

使用简单但完全编译时。

constexpr auto same_ = eq3(42,42,42);
std::bool_constant< eq3(42,42,42) > twins_ ;

对于比较整个值序列,概念是相同的,但实现会稍微复杂一些。

template<typename ... T>
constexpr bool all_equal ( const T & ... args_ )  
{
    if ((sizeof...( args_) ) < 2) return true;
    // for non recursive version
    const auto il_ = { args_ ... };
    // compare them all to the first
    auto first_ = *(il_.begin()) ;
    // assumption
    bool rezult_{ true }; 
    for ( auto && elem_ : il_) {
        // yes I know, first cycle compares first_ to itself ...
        rezult_ = rezult_ && ( first_ == elem_ );
        // short circuit-ing
        if (!rezult_) break;
    }
    return rezult_; 
};

只是一个函数,编译时执行,没有可变参数模板的花招。

    bool_constant< all_equal(42,42,42,42,42,42,42) > same_ ;
    cout << endl << boolalpha <<  same_() ;

    bool_constant< all_equal(42,43,44,45,46,47) > not_same_ ;
    cout << endl << boolalpha <<  not_same_() ;

必须 这里有Wandbox

ps:有点可预测的 all_equal 在最新的CL版本(也称为MSVC或Visual Studio)下无法编译。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接