考虑我有以下内容:
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,那么是否计算一个表达式,其中'和'是操作数之间的运算符停止?
答案 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)
布尔表达式是短路评估的,所以如果第一部分失败,第二部分将不会运行。所以第一个例子不会访问不存在的内存,但第二个例子将会访问。