std::stack 是不是公开迭代器?
Posted
技术标签:
【中文标题】std::stack 是不是公开迭代器?【英文标题】:Does std::stack expose iterators?std::stack 是否公开迭代器? 【发布时间】:2010-10-06 05:42:49 【问题描述】:C++ STL 中的std::stack
是否公开了底层容器的任何迭代器,还是我应该直接使用该容器?
【问题讨论】:
【参考方案1】:如果您需要带有迭代器的堆栈,您有两种选择:
std::vector
使用 push_back()
、pop_back()
。
std::deque
与 push_back()
/pop_back()
或 push_front()
/pop_front()
。
【讨论】:
【参考方案2】:你在问
std::stack 是否公开迭代器?
很多人都给出了答案。如果我的英语更好,我可能也会理解“暴露”的确切含义。
如果我们指的是 STL 和类 std::stack 以及这里定义的预定义函数,答案是否定的。
我的猜测是你在问,因为你想要迭代器。
所以,如果我们更进一步,我们就有了函数 top()。并且 top() 可以解释为取消引用的迭代器。有了它,我们可以很容易地定义迭代器来堆叠元素。堆栈的内存保证是连续的。
见下文。我们正在为 std::copy 定义和使用迭代器:
#include <vector>
#include <stack>
#include <iostream>
#include <algorithm>
#include <iterator>
#include <sstream>
using Number = int;
using UnderlyingContainer = std::vector<Number>;
using Stack = std::stack< Number, UnderlyingContainer>;
using StackIterator = const Number *;
std::istringstream testData("5 8 1 4 9 3");
int main()
// Put the test data onto the stack
Stack stack UnderlyingContainer std::istream_iterator<Number>(testData),std::istream_iterator<Number>() ;
// Print the test data
// Get iterators
StackIterator end = &stack.top() + 1;
StackIterator begin = end - stack.size();
if (not stack.empty())
std::copy(begin, end, std::ostream_iterator<Number>(std::cout, "\n"));
return 0;
因此您可以为堆栈创建迭代器。但是,请注意:
std::stack 有意将其元素隐藏在底层。因此,如果您对数据进行写访问,我会将其视为设计错误。通过 const 指针/迭代器进行读取访问对我来说是可以的。但也许你应该更好地使用 std::vector 。 . .
【讨论】:
【参考方案3】:std::stack
确实通过其受保护的接口将其底层容器(以及迭代器)暴露给子类。 std::stack
的底层容器对象对应于(受保护的)数据成员c
。
所以如果你想访问它们,你可以扩展std::stack
一点。
template<typename T, typename Container = std::deque<T>>
class iterable_stack
: public std::stack<T, Container>
using std::stack<T, Container>::c;
public:
// expose just the iterators of the underlying container
auto begin() return std::begin(c);
auto end() return std::end(c);
auto begin() const return std::begin(c);
auto end() const return std::end(c);
;
int main()
iterable_stack<int> st;
st.push(2);
st.push(5);
st.push(3);
st.push(7);
st.push(9);
for(auto i: st)
std::cout << i << ' ';
std::cout << '\n';
输出:
2 5 3 7 9
【讨论】:
嗨,我正在尝试弄清楚如何使用 ::c ...但尚未成功。你能解释一下我们如何通过使用 ::c 在 Stack 上获得一个迭代器吗?我看到它“链接”到 container_type,但我现在的想法还不清楚。 ::c 的解释真的很有帮助!在此先感谢...【参考方案4】:根据堆栈的定义,堆栈没有迭代器。如果您需要带有迭代器的堆栈,则需要在其他容器(std::list、std::vector 等)之上自己实现它。 Stack doc is here.
附:根据我从 Iraimbilanja 得到的评论,std::stack 默认使用 std::deque 来实现。
【讨论】:
+1。另请注意,默认情况下 std::stack 使用 std::deque 作为其实现,因此这对于 iterstack 的默认实现也可能是一个不错的选择。另一个问题是,为什么你想要一个可迭代的堆栈,而不是一个直接的双端队列【参考方案5】:在SGI、MSDN 和GNU 文档中,stack
不提供迭代器。
【讨论】:
以上是关于std::stack 是不是公开迭代器?的主要内容,如果未能解决你的问题,请参考以下文章