C ++ 11。
如果我尝试从空的pop
开始priority_queue,
,则会收到编译时错误。具体来说,
#include <iostream>
#include <queue>
int main()
{
std::priority_queue<int> pq;
int x = pq.pop();
std::cout << x << std::endl;
}
产生编译时错误:
In function 'int main()': 7:20: error: void value not ignored as it ought to be
我很惊讶这是一个编译时错误,而不是运行时错误,但这是另一次讨论。
我不明白为什么top
方法不会做同样的事情。实际上,如果我们将pop
更改为top
,则代码实际上会编译并运行(尽管输出是bizzare)。具体来说,
#include <iostream>
#include <queue>
int main()
{
std::priority_queue<int> pq;
int x = pq.top();
std::cout << x << std::endl;
}
此代码可以正常编译,运行和退出,但不产生任何输出!它实际上不打印任何内容。我不知道怎么回事。
这是我的问题:
如果pop
为空,是否定义了top
和priority_queue
的行为?我没有提到这种情况in the docs。
在第二种情况下怎么没有输出? top
返回一个常量引用。因此,它必须指向某物。我可以想象它只是将它指向的任何内存解释为整数。但这似乎没有发生。似乎整数的行为类似nullptr
。
答案 0 :(得分:3)
int x = pq.pop();
pop
返回void
。将void
分配给变量的格式不正确。如错误所示:
void value not ignored as it ought to be
另一方面:
int x = pq.top();
将整数分配给变量的格式正确。
- 如果priority_queue为空,是否定义了pop和top的行为?
不。该行为是未定义的(对于std::priority_queue<int>
。该行为可能是为其他基础容器定义的。)
- 第二种情况下怎么没有输出?
行为是不确定的。
具体地说,我认为UB意味着您不知道变量x的含义。
是正确的,但是对UB的描述不完整。 UB意味着您无法预测有关程序行为的任何信息。
答案 1 :(得分:3)
在空的priority_queue
上调用std::priority_queue::top
的行为取决于基础容器。
引用顶部元素,就像通过调用
获得的一样c.front()
如您的代码所示,默认参数std::vector
被用作基础容器,并且在空容器上调用std::vector::front
的行为是不确定的。这意味着一切皆有可能。
在空容器上调用前台是不确定的。
与std::priority_queue::pop
类似,它将在基础容器上调用pop_back
;对于std::vector::pop_back
,在空容器上调用它也是UB。
在空容器上调用pop_back是未定义的。
最后,std::priority_queue::pop
不返回任何内容;这就是int x = pq.pop();
不起作用的原因(错误消息试图告诉您)。
答案 2 :(得分:3)
您错误地使用了priority_queue
。 pop()
上的From the docs:
返回值
(无)
但是,您尝试将其绑定到整数变量。与
相同void f() {};
int n = f();
,没有任何意义。此外,对于
int x = pq.top();
我们再次得出from the docs的结论
引用顶部元素,就像通过调用
获得的一样c.front()
因此,行为取决于基础容器的front()
成员函数。在您的示例中,这是默认值std::vector
,因此是from the docs:
返回对容器中第一个元素的引用。
在空容器上调用front是未定义的。
您在UB土地上,因此不要尝试从程序输出中得出任何结论。