Frage

Ich brauche über std::queue iterieren. www.cplusplus.com sagt:

  

In der Standardeinstellung, wenn keine Container-Klasse für eine bestimmte Warteschlange Klasse angegeben ist, wird die Standard-Container-Klasse-Vorlage deque verwendet.

So kann ich irgendwie auf die zugrunde liegenden deque Warteschlange und iterieren es?

War es hilfreich?

Lösung

Wenn Sie eine queue iterieren müssen, dann müssen Sie etwas mehr als eine Warteschlange. Der Punkt, der Standard-Container-Adapter ist eine minimale Schnittstelle. Wenn Sie auch tun Iteration müssen, warum nicht nur eine deque (oder Liste) statt?

Andere Tipps

Während ich mit anderen, dass die direkte Verwendung eines iterable Behälter vereinbaren eine bevorzugte Lösung ist, möchte ich darauf hinweisen, dass der C ++ Standard genug Unterstützung für eine garantiert Do-it-yourself-Lösung, falls Sie es aus irgendeinem Grund.

Das heißt, können Sie von std::queue erben und seinen geschützten Mitglied Container c; verwenden, um Zugriff auf begin () und end () des darunter liegenden Behälters (vorausgesetzt, dass diese Methoden existieren). Hier ist ein Beispiel, das in VS 2010 arbeitet und getestet mit 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;
}

können Sie die ursprüngliche Warteschlange in eine temporäre Warteschlange speichern. Dann tun Sie einfach Ihren normalen Pop auf der temporären Warteschlange durch das Original zu gehen, zum Beispiel:

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();
} 

Am Ende wird die tmp_q leer sein, aber die ursprüngliche Warteschlange ist unberührt.

Warum nicht einfach eine Kopie der Warteschlange, die Sie iterieren möchten, und Elemente einer nach dem anderen entfernen, sie zu drucken, wie Sie gehen? Wenn Sie mehr mit den Elementen tun möchten, wie Sie durchlaufen, dann eine Warteschlange ist die falsche Datenstruktur.

Alexey Kukanov Antwort effizienter sein können, können Sie auch auf ganz natürliche Art und Weise über eine Warteschlange durchlaufen, die von jedem Aufspringen Element aus der Vorderseite der Warteschlange, drückt es dann auf die Rückseite:

#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();
    }
}

Ausgabe:

0 1 4 9 16 25 36 49 64 81 

Wenn Sie eine Warteschlange zu wiederholen brauchen ... Warteschlange ist nicht der Container, den Sie brauchen.
Warum haben wählen Sie eine Warteschlange?
Warum Sie nicht über einen Container nehmen, die Sie durchlaufen können?


1.if Sie eine Warteschlange wählen dann sagen Sie, Sie einen Container in eine ‚Warteschlange‘ Schnittstelle wickeln möchten:     - Vorderseite     - zurück     - drücken     - pop     - ...

Wenn Sie auch iterieren wollen, hat eine Warteschlange eine falsche Schnittstelle. Eine Warteschlange ist ein Adapter, der eine eingeschränkte Teilmenge des ursprünglichen Container

bietet

2. Die Definition einer Warteschlange ist ein FIFO und per Definition ein FIFO ist nicht iterable

Ich benutze so etwas wie diese. Nicht sehr anspruchsvoll, aber sollte funktionieren.

    queue<int> tem; 

    while(!q1.empty()) // q1 is your initial queue. 
    {
        int u = q1.front(); 

        // do what you need to do with this value.  

        q1.pop(); 
        tem.push(u); 
    }


    while(!tem.empty())
    {
        int u = tem.front(); 
        tem.pop(); 
        q1.push(u); // putting it back in our original queue. 
    }

Es wird denn arbeiten, wenn Sie etwas von q1 Pop, und schieben Sie es in tem, wird es das erste Element des tem. Also, am Ende tem wird eine Replik der q1.

. Kurz: Nein

Es ist ein Hack, Verwendung Vektor als unterlegtem Behälter, so queue::front wird gültige Referenz zurückgeben, wandeln sie einen Iterierte auf Zeiger, bis <= queue::back

std::queue ist ein Container-Adapter, und Sie können die Container angeben verwendet (es standardmäßig eine deque zu verwenden). Wenn Sie Funktionalität über die im Adapter benötigen dann benutzen Sie einfach einen deque oder einen anderen Container direkt an.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top