web-dev-qa-db-ja.com

std :: stackはイテレータを公開しますか?

std::stack C++ STLで、基になるコンテナーのイテレーターを公開するか、そのコンテナーを直接使用する必要がありますか?

34
mdm

スタックの定義により、スタックには反復子がありません。イテレータとのスタックが必要な場合は、他のコンテナ(std :: list、std :: vectorなど)の上に自分で実装する必要があります。 Stack docはこちら

追伸Iraimbilanjaから得たコメントによると、デフォルトではstd :: stackは実装にstd :: dequeを使用しています。

37
Drakosha

イテレータ付きのスタックが必要な場合は、2つの選択肢があります。 Push_back()、pop_back()を使用したstd :: vector std :: dequeとPush_back()/ pop_back()またはPush_front()/ pop_front()。

12
paxos1977

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 
2
Galik

[〜#〜] sgi [〜#〜][〜#〜] msdn [〜#〜] および [〜#〜] gnu [ 〜#〜] ドキュメンテーション、stackはイテレータを提供していません。

1
Hosam Aly

頼むよ

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を使うべきです。 。 。

0
Armin Montigny