【问题标题】:Why comparing three variables together with == evaluates to false?为什么将三个变量与 == 一起比较的结果为假?
【发布时间】:2020-02-04 20:16:56
【问题描述】:

以下程序的输出是“它们不相等”,但我希望“它们相等”,因为三个比较变量(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";
    }
}

【问题讨论】:

  • if (x == y == z) 没有按照你的想法做
  • 所以我不能在一行中等效 3 个数字而不分别等效每个 2 个数字?
  • 所以我不能在一行中等效 3 个数字而不分别等效每个 2 个数字?你是对的,你不能这样做单个表达式
  • 正确。因为比较计算结果为布尔值,然后您将其与数字进行比较。

标签: c++


【解决方案1】:

现在还有一些实用的 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 is here

ps:有点可预测 all_equal 不使用最新的 CL (也称为 MSVC 或 Visual Studio)进行编译。

【讨论】:

    【解决方案2】:

    这是因为表达式和类型的计算方式。

    让我们评估最左边的==

    x == y ...
    

    这评估为真。让我们重写表达式:

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

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

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

    但是z 不等于1。那句话是假的!

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-12-05
      • 2014-06-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-07
      • 1970-01-01
      相关资源
      最近更新 更多