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

Using the comma operator with the conditional operator

我正在学习 C++,在使用 ,?: 运算符时偶然发现了以下行为。条件运算符的语法类似于 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;
}

并输出:

x !> y
x is not greater than y

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

x > y
x is greater than y
x is not greater than y

但我期待:

x > y
x is greater than y

所以即使表达式 E1 的结果是 true.

,也会计算表达式 E3 的最后部分

但是,当我将 E2 和 E3 放在括号内时,程序的输出在两种情况下都符合预期:x > y 和 x < y。根据 [1],逗号 , 位于操作数 E1 和 E2 的运算符上,如 E1, E2 中那样,它本身就是一个表达式,由 [1]。基于此,我不明白为什么 ?: 运算符的表达式 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

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

foo ? a(), b() : c(), d();

我们遇到的第一个运算符是条件运算符(§7.6.16):

conditional-expression:
    logical-or-expression
    logical-or-expression ? expression : assignment-expression

第二个操作数可以是表达式,a(), b()是复合表达式。 然而,第三个操作数只能是赋值表达式 (§7.6.19):

assignment-expression:
    conditional-expression
    yield-expression
    throw-expression
    logical-or-expression assignment-operator initializer-clause
assignment-operator: one of
    =  *=  /=  %=   +=  -=  >>=  <<=  &=  ^=  |=
c(), d()

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

expression:
    assignment-expression
    expression , assignment-expression

A pair of expressions separated by a comma is evaluated left-to-right; the left expression is a discarded-value expression. Every value computation and side effect associated with the left expression is sequenced before every value computation and side effect associated with the right expression. [...]

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