web-dev-qa-db-ja.com

std :: queueの繰り返し

std::queueを反復処理する必要があります。 www.cplusplus.comのコメント:

デフォルトでは、特定のキュークラスにコンテナクラスが指定されていない場合、標準のコンテナクラステンプレートdequeが使用されます。

だから私はどういうわけかキューの基になる両端キューに到達し、それを反復処理できますか?

63
jackhab

queueを反復処理する必要がある場合は、キュー以外のものが必要です。標準のコンテナアダプタのポイントは、最小限のインターフェイスを提供することです。繰り返しを行う必要がある場合は、代わりにdeque(またはリスト)を使用するだけではどうですか?

63
CB Bailey

反復可能なコンテナを直接使用することが推奨されるソリューションであることに他の人も同意しますが、何らかの理由で必要な場合に備えて、C++標準が日曜大工ソリューションの十分なサポートを保証することを指摘したいと思います。

つまり、std::queueを継承し、その保護されたメンバーContainer c;を使用して、基になるコンテナのbegin()およびend()にアクセスできます(そのようなメソッドが存在する場合)。 VS 2010および ideoneでテスト済み で動作する例を次に示します。

#include <queue>
#include <deque>
#include <iostream>

template<typename T, typename Container=std::deque<T> >
class iterable_queue : public std::queue<T,Container>
{
public:
    typedef typename Container::iterator iterator;
    typedef typename Container::const_iterator const_iterator;

    iterator begin() { return this->c.begin(); }
    iterator end() { return this->c.end(); }
    const_iterator begin() const { return this->c.begin(); }
    const_iterator end() const { return this->c.end(); }
};

int main() {
    iterable_queue<int> int_queue;
    for(int i=0; i<10; ++i)
        int_queue.Push(i);
    for(auto it=int_queue.begin(); it!=int_queue.end();++it)
        std::cout << *it << "\n";
    return 0;
}
33
Alexey Kukanov

元のキューを一時キューに保存できます。次に、一時キューで通常のポップを行うだけで、元のキューを通過できます。次に例を示します。

queue tmp_q = original_q; //copy the original queue to the temporary queue

while (!tmp_q.empty())
{
    q_element = tmp_q.front();
    std::cout << q_element <<"\n";
    tmp_q.pop();
} 

最後に、tmp_qは空になりますが、元のキューは変更されません。

9
StupidMe

繰り返したいキューのコピーを作成し、アイテムを一度に1つずつ削除して、それらを印刷していきませんか?繰り返しながら要素をさらに使いたい場合、キューは間違ったデータ構造です。

1
Chuck

Alexey Kukanov's answer の方が効率的かもしれませんが、キューの先頭から各要素をポップし、最後にプッシュすることで、非常に自然な方法でキューを反復処理することもできます。

#include <iostream>
#include <queue>

using namespace std;

int main() {
    //populate queue
    queue<int> q;
    for (int i = 0; i < 10; ++i) q.Push(i);

    // iterate through queue
    for (size_t i = 0; i < q.size(); ++i) {
        int elem = std::move(q.front());
        q.pop();
        elem *= elem;
        q.Push(std::move(elem));
    }

    //print queue
    while (!q.empty()) {
        cout << q.front() << ' ';
        q.pop();
    }
}

出力:

0 1 4 9 16 25 36 49 64 81 
0
Vaelus