为什么运算符`?:`没有优先级?

时间:2014-08-06 14:32:22

标签: c++

调试后我发现三元运算符?:没有优先权。我的问题是为什么?
我有以下代码:

bool T = true;
cout << ((T == true) ? "true" : "false") << endl;
cout << (T == true) ? "true" : "false";

输出:

true
1

现场演示:http://ideone.com/Tkvt9q

7 个答案:

答案 0 :(得分:35)

条件运算符确实具有优先权(尽管其三元性质略微复杂);但这个优先级非常低。由于它低于<<,因此第二个被解析为

(cout << (T == true)) ? "true" : "false";

流式传输T == true的布尔值,然后评估(但忽略)表达式"true"。如果您启用一组合理的警告,大多数编译器都会发出警告。

以下是对运算符优先级的引用,显示<<的优先级(7)高于?:(15):http://en.cppreference.com/w/cpp/language/operator_precedence

答案 1 :(得分:29)

条件运算符? :确实具有优先级 - 它在this table中的数字15,低于<<>>运算符,它们是第七个。< / p>

我遵循以避免这样的错误的规则是在有疑问时使用括号。理由很简单:如果你需要在表格中查找优先级,很有可能你的代码的读者,包括你自己,需要在以后做同样的事情。

答案 2 :(得分:11)

很多其他问题都回答了为什么你会看到这种行为,但他们没有回答为什么三元运营商的优先级低。

由于我们不想要代码

,因此决定具有较低的三元优先级
a<d ? 10 : 100

结束意义

a < (d ? 10 : 100) //BAD: not what we normally expect

我们希望它意味着

(a<d) ? 10 : 100 

三元运营商的低优先级实现了这一目标。这种事情是您在语言中找到的运算符优先级的全部原因。目标是方便编写预期在语言中正常的表达式。对?如果没有,它可以用括号左右。这对使用起来很烦人,你很快就会提出一些方便的运算符优先级。

答案 3 :(得分:7)

?:运算符确实没有明确定义的优先级。但是这个例子并没有真正说明这一点。 <<?:的相对优先级相当明确。您的所有示例都显示<<的优先级高于?:的优先级。

至于?:运算符优先级的更一般性问题... ?:运算符与其他运算符相比具有相对复杂的格式:它有三个非均匀操作数。由于这种不均匀性,?之前的部分与?之后的部分具有不同的句法分组属性。

毕竟,&#34;优先事项&#34;是一种衍生技巧,用于简化语法定义的句法分组的可视化和记忆。但并非所有C ++运算符都符合该技巧。 ?:运算符恰好是没有运算符的运算符,这就是为什么正确编写的优先级表通常会为?:运算符提供旁注,解释其不寻常的属性。同样,?之前的部分与?之后的部分具有不同的优先级,这就是为什么不能将?:运算符正确放置到优先级的线性表中的原因。

除非我忘记了某些内容,否则?:运营商是唯一没有直接明确优先权的运营商。

P.S。使用?:运算符的事情在C语言中更糟糕.C ++与语法相关的更改使?:更符合线性优先级的概念。

答案 4 :(得分:4)

与其他答案一样,<<运算符的优先级高于?运算符。以下是我对其原因的看法。

对选择运算符使用位移(<<)是有意义的;例如

(T == true) ? (whatever << 1) : (whatever << 2)
(T == true) ? whatever << 1 : whatever << 2 // same as above

当C ++的设计者发明运算符重载时,他们决定重用位移运算符<<作为流操作符。如果他们引入了另一个全新的流媒体运营商(例如<<<),它将获得非常低的优先级,因此代码将按预期工作:

cout <<< (T == true) ? "true" : "false";

然而,引入一个新的运算符只是为了让它过载会破坏运算符重载的有用性的想法,这是一个引人入胜的想法。所以他们决定使用旧的(现有的)运营商。

答案 5 :(得分:2)

三元条件运算符确实有一个优先级,除了它位于列表的底部(值15)。只有throw,(逗号)的优先级较低。请参阅此C++ Operator Precedence的参考资料。

答案 6 :(得分:0)

因为括号,首先评估语句(T == true),然后左移位运算符和先前评估的1被发送到cout。之后,三元运算符会对"true"进行求值,但会被忽略。

总而言之,三元运算符具有优先权,但是最低的一个。