将 std::stack 复制到 std::vector

Posted

技术标签:

【中文标题】将 std::stack 复制到 std::vector【英文标题】:Copy std::stack into an std::vector 【发布时间】:2011-05-19 18:17:39 【问题描述】:

标准是否保证以下代码可以工作(假设 st 不为空)?

#include <vector>
#include <stack>
int main()

   extern std::stack<int, std::vector<int> > st;
   int* end   = &st.top() + 1;
   int* begin = end - st.size();
   std::vector<int> stack_contents(begin, end);

【问题讨论】:

【参考方案1】:

是的。

std::stack 只是一个容器适配器。

你可以看到.top()实际上是(§23.3.5.3.1)

reference top()  return c.back(); 

其中c 是容器,在本例中是std::vector

也就是说你的代码基本翻译成:

   extern std::vector<int> st;
   int* end   = &st.back() + 1;
   int* begin = end - st.size();
   std::vector<int> stack_contents(begin, end);

由于std::vector 保证是连续的,所以应该没有问题。

但是,这并不意味着这是一个好主意。如果您需要像这样使用“hacks”,这通常表明设计不佳。您可能想从一开始就使用std::vector

【讨论】:

+1 您可以编辑已删除的回复并取消删除。 我明白了,以后会这样做的。 一些算法规定使用堆栈,并且需要在结束时以其他某种(通常是数组或向量)形式(例如,DAG 的拓扑排序)返回堆叠的元素。恕我直言,使用标准堆栈适配器而不是自己滚动是首选。最后手动从堆栈中弹出所有元素比必要的要慢,并且考虑到这里的代码完全兼容和正确,我认为它没有任何问题。在需要时将其保存在工具箱中是一个很好的模式。【参考方案2】:

C++03 仅保证 std::vector 具有连续元素 (23.4.1)。在 C++1x 中,这也将扩展到 std::string (defect #530)。

【讨论】:

哇,我从来不知道 string 没有这样的保证。有趣,谢谢。支持,虽然这与我的问题无关【参考方案3】:

是的,这是有保证的。向量保证使用连续存储,因此您的代码可以工作。虽然它有点笨拙 - 如果有人更改堆栈的底层容器类型,您的代码将继续编译而不会出错,但运行时行为将被破坏。

【讨论】:

【参考方案4】:

不幸的是,我没有参考标准来支持这一点,但我猜它可能出错的方式并不多:

std::vector&lt;int&gt;指定为容器类型意味着元素必须存储在std::vector&lt;int&gt;中。 st.top() 必须返回对底层容器中元素的引用(即std::vector&lt;int&gt; 中的元素。由于对容器的要求是支持back()push_back()pop_back(),我们可以合理假设top() 返回对向量中最后一个元素的引用。 end 因此指向最后一个元素之后的一个元素。 start 因此指向开头。

结论:除非假设是错误的,否则它必须有效。

编辑:鉴于其他答案对标准的引用,假设是正确的,所以它有效。

【讨论】:

【参考方案5】:

根据this page,std::stack使用容器类来存储元素。

我猜你的建议只有在容器以线性方式存储其元素时才有效 (std::vector)。

默认情况下,std::stack 使用 std::deque,据我所知,它不符合此要求。但是,如果您将 std::vector 指定为容器类,我看不出它不应该工作的原因。

【讨论】:

这就是为什么他指定std::vector&lt;int&gt;作为我猜的容器类型:) @sgolodetz:刚刚意识到这一点;)我现在还没有完全清醒。【参考方案6】:

编辑:最初的声明已被编辑,标准实际上确实为堆栈适配器提供了完整的定义,没有任何东西留给实施者。查看最佳答案。

您需要一个具有 push 和 pop 方法的容器,并允许您检查容器中任何位置的元素并使用 std::vector 进行存储。标准模板库中有这样一个容器

它被称为std::vector

std::stack 仅用于束缚目的

【讨论】:

以上是关于将 std::stack 复制到 std::vector的主要内容,如果未能解决你的问题,请参考以下文章

将 std::vector 复制到 qvector

预期的枚举`std::result::Result`,发现结构`std::vec::Vec`。

从deque到std::stack,std::queue,再到iOS 中NSArray(CFArray)

在堆栈中搜索特定元素

如何打印 Vec?

std::vector 与 std::stack