【问题标题】:Why does top()'s return value change after calling pop()?为什么调用pop()后top()的返回值会发生变化?
【发布时间】:2016-11-12 12:25:09
【问题描述】:

priority_queuetop() 返回的 const 引用在调用 pop() 后发生变化(Visual Studio 2015)

priority_queue<int> queue;
queue.push(1);
queue.push(2);
queue.push(3);

const int & m = queue.top();
cout << m << endl; // 3
queue.pop();
cout << m << endl; // 2
queue.pop();
cout << m << endl; // 1

如果通过auto &amp; m = queue.top(); 得到最高值,那么输出也是3 2 1

如果通过auto m = queue.top(); 获得最高值,则输出为3 3 3

这背后的机制是什么?

【问题讨论】:

  • 未定义的行为,您创建了对不再存在的元素的引用。
  • 不知道为什么这被否决了,这似乎是一个足够公平的问题

标签: c++ auto const-reference


【解决方案1】:

如果通过auto &amp; m = queue.top();得到最高值,那么输出也是3 2 1

尽管在第一次调用pop() 之后调用了未定义的行为以使用m,但下一个值很可能被移动到该悬空引用(地址)。这是因为std::priority_queue 的默认底层类型是std::vector,这保证了元素的连续数组。

但如前所述,行为是未定义的,并且无法保证使用不同的编译器重现该结果。

如果通过auto m = queue.top();获得最高值,则输出为3 3 3

top 中的值存储到m 中一次,之后就不再更改。

【讨论】:

  • 为什么 const 引用 m 不能延长返回值的生命周期? (因为返回类型是const int &amp; 而不是int?)
  • @stanleyerror 在documentation 中表示 "... 返回对优先级队列中顶部元素的引用。该元素将在调用 pop() 时被删除。"
  • @stanleyerror 您正在考虑何时将引用绑定到prvalue。但是top() 返回一个左值,而不是纯右值(另一种说法是,它通过引用返回,而不是按值返回)。暂时不涉及。
猜你喜欢
  • 2013-11-12
  • 2013-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-20
  • 2015-07-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多