【问题标题】:Why does C++ have queue and stack given it already have deque? [duplicate]为什么 C++ 有队列和堆栈,因为它已经有双端队列? [复制]
【发布时间】:2019-04-13 02:50:06
【问题描述】:

我想知道为什么 C++ 有队列和堆栈,因为它已经有双端队列。

看来stack/queue的runtime和使用deque模拟stack/queue是一样的。此外,deque 支持诸如擦除、迭代器和随机访问之类的修饰符,而堆栈或队列都不支持这些修饰符。

既然双端队列比其他两个更强大,为什么 C++ 提供所有三个呢?

谢谢!

【问题讨论】:

  • 它们不是相互排斥的。其实std::stackstd::queue都默认使用std::deque
  • 有时少即是多。 stackdeque 像堆栈一样在程序中的作用更容易理解。
  • 一种类型的“力量”通常是使用风险的代名词。更“强大”的功能使检测错误变得更加困难,因为根据定义,您不允许做的事情更少。一个典型的例子是 c 风格的演员表。它们在可以执行的转换方面非常强大,它们可以取代任何 c++ 风格的转换。但它们的力量也意味着它们使用起来很危险。因此,尽管它们使所有其他演员表变得多余,但特别不鼓励使用它们,因为它是如此强大。与其将queuestack 视为“不那么强大”,不如将它们视为更安全。
  • @FrançoisAndrieux 说得好,我想补充一点,使用queuestack 更具表现力。当堆栈是 stack 而队列是 queue 时,代码更容易推理

标签: c++ data-structures stl deque


【解决方案1】:

std::stackstd::queue 是所谓的“容器适配器”,因为它们适应被包装容器的接口(模板参数,默认为 std::deque,但可以是任何实现 back()push_back() and pop_back() for std::stack, and back(), pop_front() and push_back() for std::queue) 到栈或队列的受限接口;如果您愿意,它们可以简化底层容器接口。

一般的想法应该是“受限”容器只提供容器“预期操作模式”的操作——std::stack 只允许类似堆栈的操作,不像底层的std::deque 允许,例如,随机插入/访问。另一个优点是底层容器类型的编译时多态性比传递普通容器更舒适(您可能会收到更好的错误消息)。

在实践中,我总是发现这些适配器至少没用,更多时候只是障碍:

  • 它们不限制可用状态的空间,因为如果有额外的空间,std::stackstd::queue 都可以以任何方式进行变异;
  • 它们不提供对底层容器类型的类型擦除,因为它是一个模板参数,因此它们对于编写一个采用任何堆栈的非模板函数(无论底层容器如何)都没有用处;
  • 他们的界面通常过于受限;即使底层容器完全支持前向迭代器(甚至是随机访问),您甚至无法对 std::stack 的全部内容进行调试打印。

【讨论】:

  • 您的第二个要点很容易通过向函数添加一个额外的模板参数来克服:coliru.stacked-crooked.com/a/79028b2d002e58fe。其他点虽然非常有效。
  • @NathanOliver:这正是我在第二段中提到的关于编译时多态性的情况。但这与“常规”多态性不同,因为它使用模板感染所有东西,并且它提供的唯一优势是让函数接受通用容器,它提供了更好的错误消息。
【解决方案2】:

std::queuestd::stack 实际上并不是标准库中的容器。它们是container adaptors,它们的存在是为了在实际容器之上为您提供一个特定的界面。

您不希望您的堆栈有 operator [],因此我们包装了 std::deque(默认情况下,您可以使用不同的容器),这样我们就不会公开堆栈没有的操作。

【讨论】:

    【解决方案3】:

    std::stackstd::queue 都是容器适配器。默认情况下使用std::deque 作为后备容器,但不一定如此。

    与双端队列相比,堆栈和队列都具有简化的接口。因此,您可能希望有一个不使用 std::deque 而是使用其他容器的堆栈,这就是适配器的用途。

    【讨论】:

      猜你喜欢
      • 2014-10-14
      • 2020-04-19
      • 2013-12-13
      • 2013-09-30
      • 2018-05-09
      • 2013-09-18
      • 1970-01-01
      • 2016-11-30
      • 1970-01-01
      相关资源
      最近更新 更多