将逗号运算符与条件运算符一起使用

Fer*_*Fer 2 c++ comma-operator conditional-statements operator-keyword

,我正在学习 C++,并在使用and运算符时偶然发现了以下行为?:。条件运算符的语法如下所示E1 ? E2 : E3,其中 E1、E2 和 E3 是表达式[1],[2]。我从这段代码开始:

#include <iostream>

using namespace std;

int main(){
    int x = 20, y = 25;
    x > y ? cout << "x > y\n" , cout << "x is greater than y" : cout << "x !> y\n", cout << "x is not greater than y";
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

和输出:

x !> y
x is not greater than y
Run Code Online (Sandbox Code Playgroud)

这就是我期待的结果。但是当我更改值以int x = 25, y = 20使 x 大于 y 时,我得到以下输出:

x > y
x is greater than y
x is not greater than y
Run Code Online (Sandbox Code Playgroud)

但我期待:

x > y
x is greater than y
Run Code Online (Sandbox Code Playgroud)

因此,即使表达式的结果为E3,也会计算表达式的最后部分。E1true

但是,当我将 E2 和 E3 放在括号内时,程序的输出在两种情况下都符合预期:当 x > y 和 x < y 时。根据 [1],逗号,是 on 运算符,其操作数 E1 和 E2 与 [1] 中一样E1, E2,它本身就是一个表达式。基于此,我不明白为什么?:即使表达式为真且两者都为真,也会计算运算符的表达式 E3 的最后部分E1

我的问题是:

1)我是否正确使用了条件运算符?:

2)这种意外结果发生的机制是什么?

3)为什么使用括号可以解决问题(或者至少符合我的期望)?

我正在使用:gcc版本5.4.0 20160609(Ubuntu 5.4.0-6ubuntu1~16.04.11)

非常感谢。

[1] https://en.cppreference.com/w/cpp/language/expressions

[2] https://en.cppreference.com/w/cpp/language/operator_other

J. *_*Doe 5

为了简单起见,让我们考虑一个更容易阅读的语句:

\n\n
foo ? a(), b() : c(), d();\n
Run Code Online (Sandbox Code Playgroud)\n\n

我们遇到的第一个运算符是条件运算符(\xc2\xa77.6.16):

\n\n
conditional-expression:\n    logical-or-expression\n    logical-or-expression ? expression : assignment-expression\n
Run Code Online (Sandbox Code Playgroud)\n\n

第二个操作数可以是表达式并且a(), b()是复合表达式。\n但是第三个操作数只能是赋值表达式 ( \xc2\xa77.6.19 ):

\n\n
assignment-expression:\n    conditional-expression\n    yield-expression\n    throw-expression\n    logical-or-expression assignment-operator initializer-clause\nassignment-operator: one of\n    =  *=  /=  %=   +=  -=  >>=  <<=  &=  ^=  |=\n
Run Code Online (Sandbox Code Playgroud)\n\n
conditional-expression:\n    logical-or-expression\n    logical-or-expression ? expression : assignment-expression\n
Run Code Online (Sandbox Code Playgroud)\n\n

不是其中之一,而是逗号表达式 (\xc2\xa7 7.6.20/1 ):

\n\n
expression:\n    assignment-expression\n    expression , assignment-expression\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n

由逗号分隔的一对表达式从左到右计算;左边的表达式是丢弃值表达式。与左侧表达式关联的每个值计算和副作用都在与右侧表达式关联的每个值计算和副作用之前排序。[...]

\n
\n\n

因此,整个语句中最后一个逗号运算符左侧的所有内容都是一个废弃值表达式,该表达式在逗号运算符右侧之前进行计算(并丢弃其结果)。

\n