【问题标题】:Why does C++ standard queue have back function when stack doesn't have bottom function?当堆栈没有底部功能时,为什么 C++ 标准队列有返回功能?
【发布时间】:2014-02-25 14:14:39
【问题描述】:

在许多非官方 C++ 参考网站之一上,列出了 std::queue 的成员函数 front()back()。但是std::stack只有top()功能。

堆栈没有bottom() 函数是有意义的,因为这是堆栈的定义。

我不明白的是,为什么 C++ 标准委员会选择不遵循队列的定义并为队列提供 back() 函数并选择遵循堆栈的定义而不提供 bottom()功能。

【问题讨论】:

  • 这听起来可能有点迂腐,但 cplusplus.com 不是 C++ 参考。这是关于 C++ 的一个(=一些)网站。
  • 嗯...stack::bottomqueue::back 并不完全相似。我不认为提供back 真的是一个有趣的违规行为。你仍然被限制在 push_backpop_front,满足了 FIFO 队列的期望。
  • 添加 stack::bottom 仍然满足 LIFO。
  • @dyp 你有什么建议作为替代参考?该标准本身是付费的,不可深度链接。
  • @Adam 您可以使用n3337,这是标准加上纯粹的编辑更改,或最新的 C++1y 草案(例如通过github repository),其中还包含编译器的一些修复将在他们的 C++11 模式下实现(原文如此!)。还有另一个(= 一些)网站 cppreference.com 在 StackOverflow C++ 社区中享有盛誉。

标签: c++ stack queue std


【解决方案1】:

back() 可能还有其他原因,但您需要它作为队列,因为 C++03 中的习惯用法是将“空”对象廉价复制到容器中,然后 swapping 新元素复制起来非常昂贵的“完整”对象。由于移动语义,这个原因在 C++11 中或多或少已经过时了,但为了兼容性当然仍然需要 back()

出于那个(或任何其他)原因,您不需要 bottom() 堆栈。

【讨论】:

  • 你能详细说明为什么复制一个空对象然后交换需要一个 back() 函数或链接到我可以阅读它的地方吗?除此之外,这似乎是答案,谢谢
  • @whiteSkar 示例:考虑一个向量队列。假设每个向量都有数千个或更多元素。要将v 推到q 上,您可以执行q.push(v),但这会复制整个向量。相反,q.push(vector<int>()); q.back().swap(v);。这只是交换指针,它实际上并没有触及任何向量元素。如果推送后不使用v,那么这个方法会快很多。
  • 太棒了!现在我明白了。谢谢
  • @Adam:你也可以q.push(std::move(v));
  • @BenVoigt 肯定在 C++11 中,但史蒂夫说的是 C++03。
【解决方案2】:

它实际上以一种奇怪的方式有意义。在队列中,您从一侧推送并从另一侧弹出,因此双方很可能会发生很大变化。使用堆栈,您可以从顶部推送和弹出,而堆栈底部很少更改。因此,查询堆栈底部的当前值很少有兴趣。

【讨论】:

  • 但是在你推送之后,你不应该能够看到推送的元素,直到它到达队列的前面。
  • @Lightness:对于调试目的,查看内部元素很有用。
  • @BenVoigt:我并不否认访问非前端元素对于调试来说是伟大的(无论如何,正如史蒂夫所说,实际上有一些重要的真实-超越调试的世界用例);只是声称它具有任何语义意义。
  • @Lightness Races in Orbit:是的,但有许多基于队列的算法,根据最后推送的项目来决定是否推送新项目很有用。没有多少基于堆栈的算法可以让您根据堆栈底部的内容做出有用的决定。
猜你喜欢
  • 1970-01-01
  • 2010-09-11
  • 1970-01-01
  • 2019-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-14
  • 1970-01-01
相关资源
最近更新 更多