if(a && b)
{
do something;
}
是否有可能从右到左评估参数(b - > a)?
如果“是”,影响评估顺序的是什么?
(我正在使用VS2008)
答案 0 :(得分:55)
使用C ++,只有少数运算符可以保证评估顺序
operator &&
首先评估左操作数,如果值是逻辑false
,则它避免评估右操作数。典型的用法是if (x > 0 && k/x < limit) ...
,它可以避免零除问题。
operator ||
首先评估左操作数,如果值是逻辑true
,则它避免评估右操作数。例如,if (overwrite_files || confirm("File existing, overwrite?")) ...
在设置标记overwrite_files
时不会要求确认。
operator ,
首先评估左操作数,然后评估右操作数,返回右操作数的值。不经常使用此运算符。请注意,函数调用中参数之间的逗号是不是逗号运算符,并且无法保证评估顺序。
三元运算符x?y:z
首先评估x
,然后根据结果的逻辑值评估y
或仅评估z
。
对于所有其他运营商,未指定评估顺序。
情况实际上更糟糕,因为并不是指定了订单,而是根本没有表达式的“订单”,例如在
中std::cout << f() << g() << x(k(), h());
可能会按照h-g-k-x-f
的顺序调用函数(这有点令人不安,因为<<
运算符的心理模型以某种方式表达了顺序性的概念,但实际上只考虑了序列的顺序订单结果将放在流上,而不是按计算结果的顺序排列。)
显然,表达式中的值依赖性可能会引入一些顺序保证;例如,在上面的表达式中,保证在k()
之前调用h()
和x(...)
,因为调用x
需要两者的返回值。
另请注意,&&
,||
和,
的保证仅对预定义的运算符有效。如果你为你的类型重载那些运算符,它们就像普通函数调用一样,并且操作数的评估顺序将是未指定的。
答案 1 :(得分:43)
评估订单由标准指定,并且为left-to-right
。最左边的表达式将始终使用&&
子句进行评估。
如果您希望首先评估b
:
if(b && a)
{
//do something
}
如果两个参数都是方法,并且您希望无论结果如何都要对它们进行评估:
bool rb = b();
bool ra = a();
if ( ra && rb )
{
//do something
}
答案 2 :(得分:7)
在这种情况下,由于您正在使用&&
,因此将始终首先评估a
,因为结果用于确定是否将表达式短路。
如果a
返回false,则根本不允许b
进行评估。
答案 3 :(得分:4)
内置逻辑AND运算符的第一个(左)参数的每个值计算和副作用&amp;&amp;和内置的逻辑OR运算符||在每个值计算和第二个(右)参数的副作用之前排序。
请阅读此处以获得有关规则集的更详尽解释: order evaluation
答案 4 :(得分:2)
它将从左到右进行评估,如果可以,则将评估短路(例如,如果评估结果为假,则不会评估b)。
如果您关心他们的评估顺序,您只需要在if语句中按照所需的评估顺序指定它们。
答案 5 :(得分:1)
内置&&
运算符始终首先计算其左操作数。例如:
if (a && b)
{
//block of code
}
如果a
为false
,则不会评估b
。
如果您希望首先评估b
,而仅在a
为真时评估b
,则只需反过来编写表达式:
if (b && a)
{
//block of code
}