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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/525365/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 15:47:25  来源:igfitidea点击:

Does std::stack expose iterators?

c++stlstack

提问by mdm

Does the std::stackin the C++ STL expose any iterators of the underlying container or should I use that container directly?

std::stackC++ STL 中的是否暴露了底层容器的任何迭代器,还是应该直接使用该容器?

回答by Drakosha

Stack does not have iterators, by definition of stack. If you need stack with iterators, you'll need to implement it yourself on top of other container (std::list, std::vector, etc). Stack doc is here.

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

P.S. According to a comment i got from Iraimbilanja, std::stack by default uses std::deque for implementation.

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

回答by paxos1977

If you need a stack with iterators, you have two choices. std::vector using push_back(), pop_back(). std::deque with either push_back()/pop_back() or push_front()/pop_front().

如果您需要一个带有迭代器的堆栈,您有两种选择。std::vector 使用 push_back()、pop_back()。std::deque 带有 push_back()/pop_back() 或 push_front()/pop_front()。

回答by Galik

The std::stackdoes expose its underlying container (and therefore iterators) to subclassesthrough its protected interface. The std::stack's underlying container object corresponds to the (protected) data member c. So if you want to access them, you could extend std::stacka little.

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';
}

Output:

输出:

2 5 3 7 9 

回答by Hosam Aly

In SGI, MSDNand GNUdocumentations, stackdoesn't provide an iterator.

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

回答by Armin Montigny

Yor are asking

你在问

Does std::stack expose iterators?

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

Many people gave answers. If my English would be better, I would maybe also understand the exact meaning of 'expose'.

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

If we are referring to the STL and the class std::stack and the pre defined functions defined herein, the answer is NO.

如果我们指的是 STL 和类 s​​td::stack 以及此处定义的预定义函数,答案是否定的。

My guess would be that you are asking, because you want to have iterators.

我的猜测是你在问,因为你想要迭代器。

So, if we go one step further, we have the function top(). And top() can be interpreted as a dereferenced iterator. With that, we can easily define Iterators to stack elements. The memory of the stack is guaranteed to be contiguous.

所以,如果我们再进一步,我们就有了函数 top()。而 top() 可以解释为一个解引用的迭代器。有了这个,我们可以很容易地定义迭代器来堆叠元素。栈的内存保证是连续的。

See below. We are defining and using iterators for std::copy:

见下文。我们正在为 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;
}

So you can create iterators for a stack. But, caveat:

因此,您可以为堆栈创建迭代器。但是,警告:

The std::stack intentionally hides its elements under the hood. So, if you write-access the data, I would see it as a design fault. Read-access through const pointers/iterators is for me OK. But maybe you should better use a std::vector . . .

std::stack 有意将其元素隐藏在引擎盖下。因此,如果您对数据进行写访问,我会将其视为设计错误。通过 const 指针/迭代器的读取访问对我来说是可以的。但也许你应该更好地使用 std::vector 。. .