【问题标题】:When could std::priority_queue::pop throw an exceptionstd::priority_queue::pop 什么时候可以抛出异常
【发布时间】:2018-11-17 07:13:41
【问题描述】:

std::priority_queuepop()方法没有声明noexcept,所以理论上可以抛出异常。但是它什么时候会抛出异常,这些异常可能是什么?

【问题讨论】:

标签: c++ priority-queue c++-standard-library noexcept


【解决方案1】:

它可以标记为nothrow,但不是。

为什么std::priority_queue::pop可以*不抛出

void pop();

从优先级队列中移除顶部元素。有效调用

std::pop_heap(c.begin(), c.end(), comp); c.pop_back();

c 默认为std::vector

[vector.modifiers]/4&5

void pop_back();

4/ 复杂度:T的析构函数称为次数等于被擦除元素的次数,而T的赋值运算符称为次数等于向量中元素的数量在删除元素之后

5/ 抛出:除非T的赋值运算符或移动赋值运算符抛出异常,否则什么都没有。

*所以只有T的析构函数被调用了,因为

[requirements.on.functions]/2.4

2/ 特别是,在以下情况下效果未定义:
[...]
2.4/ 如果有替换函数或处理函数或析构函数操作通过异常退出,除非在适用的必需的行为:段落中明确允许。

为什么std::priority_queue::pop 不是nothrow

由于T::~T 抛出的异常会导致 UB,因此实现可以假设它不会发生并且仍然符合标准。另一种处理方式是让此类库函数nothrow(false)而不去处理。

【讨论】:

  • erasepop_back 共享描述,但明确指出“T的赋值运算符被调用的次数等于删除元素后向量中元素的数量” .在pop_back 的情况下,擦除元素之后没有元素,所以它不应该抛出。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多