std::stack暴露迭代器吗?

38

std::stack在C++ STL中是否提供底层容器的任何迭代器,或者我应该直接使用该容器?

5个回答

45

栈本质上没有迭代器,如果您需要带有迭代器的堆栈,则需要在其他容器(std::list,std::vector等)之上自行实现它。

此处为栈文档

P.S. 根据Iraimbilanja的评论,std::stack默认使用std::deque进行实现。


3
请注意,std::stack默认使用std::deque作为其实现方式,因此这可能是iterstack的默认实现的好选择。另一个问题是,为什么你想要一个可迭代的堆栈,而不是一个普通的deque呢? - Iraimbilanja

14

如果需要带有迭代器的堆栈,您有两个选择:

  • 使用push_back()pop_back()std::vector

  • 使用push_back()/pop_back()或者push_front()/pop_front()std::deque


9

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 在堆栈上获取迭代器?我看到它与 container_type 相关联,但我的想法现在不太清晰。::c 的解释会真正有所帮助!提前感谢... - HenriBrg
最近在这里遇到了一些问题,我宁愿放弃非const的beginend - 通过迭代器修改堆栈应该是不被允许的... - Aconcagua

2

SGIMSDNGNU 的文档中,stack 没有提供迭代器。


0

您正在询问:

std::stack是否公开迭代器?

许多人给出了答案。如果我的英语更好,我可能也会理解“公开”这个词的确切含义。

如果我们指的是STL和类std :: stack以及在此定义的预定义函数,则答案为NO。

我猜想您之所以提出这个问题,是因为您想要迭代器。

因此,如果我们再进一步,我们有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……


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接