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

发布于 2024-07-12 22:21:41 字数 58 浏览 2 评论 0原文

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

无法回应 2024-07-19 22:21:42

根据堆栈的定义,堆栈没有迭代器。 如果您需要使用迭代器进行堆栈,则需要自己在其他容器(std::list、std::vector 等)之上实现它。
堆栈文档位于此处

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

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.

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

养猫人 2024-07-19 22:21:42

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

  • 使用 push_back()pop_back()

    std::vector

  • std::dequepush_back()/pop_back()push_front()/<代码>pop_front()。

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().

灼痛 2024-07-19 22:21:42

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 

The std::stack does expose its underlying container (and therefore iterators) to subclasses through 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::stack a little.

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 
古镇旧梦 2024-07-19 22:21:42

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

In SGI, MSDN and GNU documentations, stack doesn't provide an iterator.

↙温凉少女 2024-07-19 22:21:42

你在问

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 。 。 。

Yor are asking

Does std::stack expose iterators?

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

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

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.

See below. We are defining and using iterators for 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 . . .

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文