2

考虑我有以下内容:

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

即使队列可能是空的,写这样的“如果”是否安全?

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;
}

如果左操作数的计算结果为假,则计算操作数之间的运算符为“and”的表达式是否停止?

4

5 回答 5

4

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

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

但是,相反的情况并非如此,因为您检查了弹出队列size() 后的返回值。

顺便说一句,std::priority_queue提供了一个empty()我/许多人更喜欢的功能size() > 0,但这也有效。

if(!myqueue.empty() && myqueue.top().whatever()) {
    // ...
}
于 2012-04-17T18:32:31.977 回答
3

是的,这种行为是根据 C++ 标准保证的。

if (false && doSomething())

永远不会评价doSomething()

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

你应该使用!empty()而不是size() > 0

于 2012-04-17T18:31:29.333 回答
2

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

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

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

This is true whether the && is in the expression of an if statement or not. Some obfuscated code makes use of this by turning if (x) y; into x && y. Though not see as often, you can do the same with || as well.

于 2012-04-17T18:36:35.317 回答
1

此链接解释了并非所有运算符都如此,即使 && 也是如此。特别是,请注意在关联性与评估顺序的上下文中从左到右/从右到左之间的差异。http://en.cppreference.com/w/cpp/language/eval_order

于 2012-04-17T18:36:30.847 回答
0

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

于 2012-04-17T18:32:26.327 回答