评估'if'表达式

时间:2012-04-17 18:29:41

标签: c++ if-statement short-circuiting

考虑我有以下内容:

edge some_edge;
std::priority_queue<edge> my_queue;

即使队列可能为空,写出这样的'if'是否安全?

if ((my_queue.size() > 0) && (my_queue.top().weight < some_edge.weight)) {
    do_something;
}

这个怎么样?

if ((my_queue.top().weight < some_edge.weight) && (my_queue.size() > 0)) {
    do_something;
}

如果左操作数的计算结果为false,那么是否计算一个表达式,其中'和'是操作数之间的运算符停止?

5 个答案:

答案 0 :(得分:4)

C ++中的if语句从左到右关联,逻辑布尔运算符&&||是短路的,所以是的,如下所示的语句是安全的,因为它是保证你首先检查大小(假设这些操作符没有恶意重载):

if(myqueue.size() > 0 && myqueue.top().whatever) {
    // ...
}

反之则不然,因为您在弹出队列后检查size() 的返回值。

顺便说一句,std::priority_queue提供{/ 1}}函数,我/我更喜欢empty(),但这也有效。

size() > 0

答案 1 :(得分:3)

是的,这种行为是按照C ++标准保证的。

if (false && doSomething())

永远不会评估doSomething()

但是,如果重载operator&&,则会评估所有表达式,因此此行为可能会有所不同。这就是为什么触摸operator&&是个坏主意。

您应该使用!empty()代替size() > 0

答案 2 :(得分:2)

这根本不是if,而是&&。逻辑运算符(&&||)首先计算其左操作数。然后当且仅当右操作数可能影响逻辑结果时,它们会评估正确的操作数。

&&的情况下,如果左操作数的计算结果为false,则无论右操作数的值如何,结果都将为false,因此不会计算右操作数。

||的情况下,如果左操作数的计算结果为true,则无论右操作数的值如何,结果都将为true,因此不会计算右操作数。

&&是否在if语句的表达式中,这是真的。一些混淆代码通过将if (x) y;转换为x && y来利用此功能。虽然不经常看到,但 也可以使用||执行相同操作。

答案 3 :(得分:1)

此链接解释了对于所有运营商而言并非如此,即使对于&amp;&amp;也是如此。特别要注意的是,在相关性和评价顺序的背景下,从左到右/从右到左之间存在差异。 http://en.cppreference.com/w/cpp/language/eval_order

答案 4 :(得分:0)

布尔表达式是短路评估的,所以如果第一部分失败,第二部分将不会运行。所以第一个例子不会访问不存在的内存,但第二个例子将会访问。