38

C++ STL 中的是否std::stack公开了底层容器的任何迭代器,还是应该直接使用该容器?

4

5 回答 5

43

根据堆栈的定义,堆栈没有迭代器。如果您需要带有迭代器的堆栈,您需要自己在其他容器(std::list、std::vector 等)之上实现它。 堆栈文档在这里

PS 根据我从 Iraimbilanja 得到的评论,std::stack 默认使用 std::deque 来实现。

于 2009-02-08T08:02:06.357 回答
14

如果你需要一个带有迭代器的栈,你有两种选择:

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

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

于 2009-02-08T18:01:10.767 回答
7

确实通过其受保护的接口将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 
于 2018-02-27T05:43:23.850 回答
2

SGIMSDNGNU文档中,stack不提供迭代器。

于 2009-02-08T08:01:08.917 回答
0

你在问

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

很多人给出了答案。如果我的英语更好,我可能也会理解“暴露”的确切含义。

如果我们指的是 STL 和类 s​​td::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 。. .

于 2019-06-10T12:16:09.613 回答