为什么std :: priority_queue没有clear()成员函数

时间:2013-10-03 18:10:19

标签: c++ c++11 stl

我今天做了一些黑客攻击,发现std :: priority_queue没有clear()成员函数。是否有任何技术原因可以解释为什么标准委员会可能会将其排除在外?

要明确的是,我知道通过分配很容易解决这个问题:

oldPQ = std::priority_queue<int>{};

这种解决方案不太理想,因为:

  1. 它要求您重复此类型 - 这不会继续在维护下工作。正如@chris在下面指出的那样,如果您使用的是默认构造函数,则可以简化此操作,但如果您有自定义比较器,则可能无法实现。
  2. std::priority_queue不能用于需要clear()成员函数的模板化函数。
  3. 通常不希望它不符合其他容器提供的公共接口。特别是,从std::forward_liststd::unordered_mapstd::string的所有内容都有clear()。我注意到的唯一其他异常是std :: array,其语义没有意义,std::stackstd::queue,当std::deque无任何工作时,语义更有问题额外的努力。
  4. 一个看似问题的项目,但实际上不一定是: 因为用于std::priority_queue的内部容器是模板化的,并且可能没有自己的clear()成员函数,这会产生一个有趣的问题,特别是它引发了向后兼容性的问题。这不是问题,因为:

    1. 对于不提供clear()的内部容器,只要没有人试图调用std::priority_queue::clear(),代码就会继续编译。
    2. SFINAE可能仍然可以通过在内部容器可用时调用clear()来提供新接口(清除成员),如果不可用则反复弹出。
    3. 我认为这是C ++标准的缺陷。假设技术讨论没有提供为什么省略这种方法的强有力的理由,我打算继续创建标准提案。

      编辑:

      似乎这是在委员会内处理的(注意上一篇文章):https://groups.google.com/a/isocpp.org/forum/?fromgroups#!searchin/std-discussion/clear/std-discussion/_mYobAFBOrM/ty-2347w1T4J

      http://wg21.cmeerw.net/lwg/issue2194

1 个答案:

答案 0 :(得分:5)

众所周知,容器适配器的规范过于迂腐:因为相应数据结构的“抽象”规范(来自某些关于抽象算法和数据结构的书)不包含 clear 操作规范优先级队列或堆栈,适配器中未提供。这确实经常使得在实践中使用这些适配器非常不方便。

但好消息是内部容器成员在适配器内声明为适配器的 protected 成员,名为c。这可能是专门为您能够轻松实现您自己的适配器版本:通过继承标准适配器并添加您要添加​​的任何成员函数,包括clear

至于将这些适配器的接口与标准容器接口进行比较......我认为这不是一个有效的比较。这些适配器从未打算在接口方面与容器兼容。恰恰相反,这些适配器的目的主要是限制数据结构的公共接口,并将其强制纳入其规范抽象定义所允许的范围的狭窄范围内。

例如,不允许您遍历规范堆栈。根据定义,堆栈不是“可迭代的”。堆栈适配器禁用迭代接口的事实是一件好事。但clear的缺席肯定感觉太迂腐,因为它具有很大的实用价值,而不会像规范界面那样严重违反。