Domanda

Ho bisogno di iterare su std::queue. www.cplusplus.com dice:

  

Per impostazione predefinita, se non viene specificata classe contenitore per una particolare classe di coda, viene utilizzato il modello di classe contenitore deque standard.

Quindi posso in qualche modo arrivare al deque alla base della coda e scorrere su di esso?

È stato utile?

Soluzione

Se avete bisogno di iterare su una queue allora avete bisogno di qualcosa di più di una coda. Il punto di adattatori contenitori standard è di fornire un'interfaccia minimale. Se avete bisogno di fare l'iterazione così, perché non basta usare un deque (o lista), invece?

Altri suggerimenti

Mentre sono d'accordo con gli altri che l'uso diretto di un contenitore iterabile è una soluzione preferita, voglio far notare che lo standard C ++ garantisce un sostegno sufficiente per un fai-da-te soluzione nel caso in cui lo si vuole per qualsiasi motivo.

In particolare, è possibile ereditare da std::queue e usare il suo Container c; membro protetto per accedere begin () e la fine () del contenitore sottostante (a condizione che tali metodi esistono lì). Ecco un esempio che funziona in VS 2010 e testato con 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;
}

è possibile salvare la coda originale a una coda temporanea. Quindi è sufficiente fare il vostro pop normale sulla coda temporanea di passare attraverso quella originale, per esempio:

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

Alla fine, il tmp_q sarà vuota, ma la coda originale è intatto.

Perché non basta fare una copia della coda che si desidera iterare, e rimuovere gli elementi uno alla volta, stamparli come si va? Se si vuole fare di più con gli elementi come eseguire iterazioni, poi una coda è la struttura di dati sbagliato.

mentre la risposta di Alexey Kukanov può essere più efficiente, è anche possibile scorrere una coda in un modo molto naturale, estraendo ogni elemento dalla parte anteriore della coda, poi spingendolo verso la parte posteriore:

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

uscita:

0 1 4 9 16 25 36 49 64 81 

Se avete bisogno di iterare una coda ... coda non è il contenitore che vi serve.
Perché hai scelto una coda?
Perché non prendere un contenitore che si può iterare?


1.if si sceglie una coda poi dici che vuoi per avvolgere un contenitore in un'interfaccia 'coda':     - davanti     - indietro     - spingere     - pop     - ...

se anche voi volete iterare, una coda ha un'interfaccia non corretta. Una coda è un adattatore che fornisce un sottoinsieme ristretto di contenitore originale

definizione 2. di una coda è un FIFO e, per definizione, un FIFO non è iterabile

Io uso qualcosa di simile. Non molto sofisticato, ma dovrebbe funzionare.

    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. 
    }

Si lavorerà perché quando si pop qualcosa da q1, e spingerla in tem, diventa il primo elemento di TEM. Così, alla fine tem diventa una replica di Q1.

In breve:. No

C'è un hack, uso vettore come contenitore underlaid, così queue::front tornerà riferimento valido, convertirlo in un puntatore iterare fino a <= queue::back

std::queue è un adattatore del contenitore, ed è possibile specificare il contenitore utilizzato (il default per usare un deque). Se avete bisogno di funzionalità oltre che l'adattatore poi basta usare un deque o di un altro contenitore direttamente.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top