【问题标题】:Why does std::queue not have operator[]?为什么 std::queue 没有 operator[]?
【发布时间】:2011-08-31 19:03:22
【问题描述】:

std::queue 默认使用双端队列实现。 std::deque 具有下标运算符 operator[],并且可能使用数组实现。那么为什么std::queue 没有operator[]

我意识到你可以有一个带有列表的队列作为底层容器。 (std::queue<int, std::list<int>>.) 但即使这会使下标运算符变慢,这真的是不包含它的好理由吗?这是我能想到的不包括在内的唯一原因。

【问题讨论】:

  • 如果需要operator[],为什么要使用队列?
  • 嗯,真正的原因是,这是我去年担任实验室导师时其他学生的作业的一部分。他们应该专门使用队列,但如果他们能在前面看到一些元素,那就容易多了。真的是人为的原因。 :P 在现实生活中我只会使用双端队列。

标签: c++ queue subscript-operator


【解决方案1】:

因为队列的定义不支持这样的接口。队列是一种先进先出的数据结构,即先进先出。队列支持 enqueuedequeue 操作。

将队列想象为管道:您将数据插入一端,然后从另一端取出 - 一个接一个。插入数据称为入队,取出数据称为出队。 C++ 标准库有std::queue,它定义了这两个操作:push() 是入队操作的名称,出队操作分为两个步骤,即front() 后跟pop()。 dequeue 分为两个步骤的基本原理是提供强大的异常保证1

Wikipedia 简要解释了这一点,

队列是一种特殊的集合,其中集合中的实体保持有序,对集合的主要(或唯一)操作是将实体添加到后端终端位置并从前端移除实体终端位置。这使得队列成为先进先出 (FIFO) 数据结构。 在先进先出数据结构中,第一个加入队列的元素将是第一个被移除的元素。这相当于要求一旦添加了一个元素,之前添加的所有元素都必须在调用新元素之前将其删除。队列是线性数据结构的一个例子。

1.如果你想知道它给出的强异常保证有多准确,那么你可以开始另一个话题,因为它的故事很长,需要很大的耐心才能正确理解。为此,我建议您阅读 Herb Sutter 撰写的 Exceptional C++。

【讨论】:

  • 查看队列中的元素可能仍然有用,而不是下一个要弹出的元素。如果队列支持size() 方法,为什么当底层容器支持它们时它们也不能公开迭代器(甚至operator[])?因为界面是故意简约的。它不支持operator[](或迭代器)的唯一原因是标准委员会想要一个“纯”队列接口。
  • @Andre:我认为你说的是​​真的。但是在这种情况下,第一个问题是:为什么它提供size()back() 接口,这与队列的定义不符。但似乎他们想要提供比队列应该拥有的更多功能(根据定义),同时,他们想让它变得简约。
  • 在任何情况下,它都必须提供size()empty() 以便您可以遵守front() 的先决条件(必须确保队列至少包含一个元素)。标准库的许多实例可以使用一些方便的重载(例如 for_each 的版本,它计算 .begin().end() 本身)用于常见情况。原因总是 1) 监督; 2) 保持接口一致; 3) 使标准尽可能短。值得庆幸的是,C++11 正在解决其中的一些问题。
  • @Andre:每个标准容器都支持sizeback。并非每个标准容器都支持operator[]。如果他们把它放到std::queue 中,它不仅不再是一个队列,而且你不能再使用std::list 作为它的存储空间了。
  • @Nicol:因为没有实例化未使用的模板函数,你仍然可以使用std::list作为容器,你只是不能使用std::queue<T,std::list<T>>::operator[]
【解决方案2】:

这是一个概念问题。在队列中,您添加到后面并从前面而不是从中间取出

【讨论】:

    【解决方案3】:

    之所以不包含它,是因为队列是一种具有入队和出队操作的数据结构,而不是随机访问。 std::queue的存在是为了将现有容器适配成队列接口,所以只提供队列接口。

    【讨论】:

      【解决方案4】:

      如果您想使用 [],请使用带有 push_front 和 back/pop_back 的双端队列,而不是队列。

      为什么双端队列有它但没有队列对我来说也没有意义。

      【讨论】:

        猜你喜欢
        • 2010-11-09
        • 2015-03-14
        • 1970-01-01
        • 1970-01-01
        • 2015-04-02
        • 2018-08-13
        • 1970-01-01
        • 2021-01-02
        • 2020-05-03
        相关资源
        最近更新 更多