std :: queue итерация - PullRequest
       23

std :: queue итерация

60 голосов
/ 11 августа 2009

Мне нужно перебрать std::queue. www.cplusplus.com говорит:

По умолчанию, если класс контейнера не указан для определенного класса очереди, используется стандартная deque шаблона класса контейнера.

Так можно ли как-нибудь добраться до базовой очереди очереди и перебрать ее?

Ответы [ 8 ]

61 голосов
/ 11 августа 2009

Если вам нужно перебрать queue, вам нужно нечто большее, чем очередь. Смысл стандартных контейнерных адаптеров - обеспечить минимальный интерфейс. Если вам также необходимо выполнить итерацию, почему бы не использовать вместо нее deque (или list)?

32 голосов
/ 13 мая 2011

Хотя я согласен с другими, что прямое использование итерируемого контейнера является предпочтительным решением, я хочу отметить, что стандарт C ++ гарантирует достаточную поддержку для самостоятельного решения на тот случай, если вы захотите его по какой-либо причине. 1001 *

А именно, вы можете наследовать от 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;
}
9 голосов
/ 13 апреля 2017

вы можете сохранить исходную очередь во временную очередь. Затем вы просто делаете обычное всплывающее окно во временной очереди, чтобы просмотреть исходную, например:

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 будет пустым, но исходная очередь не будет затронута.

1 голос
/ 05 декабря 2012

Почему бы просто не сделать копию очереди, для которой вы хотите выполнить итерацию, и удалять элементы по одному, печатая их по ходу? Если вы хотите сделать больше с элементами во время итерации, тогда очередь - неправильная структура данных.

0 голосов
/ 27 ноября 2018

Я использую что-то вроде этого. Не очень сложно, но должно работать.

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

Это будет работать, потому что когда вы извлекаете что-то из q1 и помещаете это в tem, это становится первым элементом tem. Таким образом, в итоге tem становится точной копией q1.

0 голосов
/ 04 декабря 2012

std::queue - это адаптер контейнера, и вы можете указать используемый контейнер (по умолчанию используется deque). Если вам нужна функциональность, выходящая за пределы адаптера, просто используйте deque или другой контейнер напрямую.

0 голосов
/ 11 августа 2009

Если вам нужно перебрать очередь ... очередь - это не тот контейнер, который вам нужен.
Почему вы выбрали очередь?
Почему бы вам не взять контейнер, который вы можете перебрать?


1.Если вы выбираете очередь, то говорите, что хотите обернуть контейнер в интерфейс «очереди»: - фронт - назад - От себя - поп - ...

если вы также хотите выполнить итерацию, у очереди неверный интерфейс. Очередь - это адаптер, предоставляющий ограниченное подмножество исходного контейнера

2. Определение очереди - это FIFO, и по определению FIFO не повторяется

0 голосов
/ 11 августа 2009

Короче говоря: №

Есть хак, используйте vector как подложный контейнер, поэтому queue::front вернет действительную ссылку, преобразует ее в указатель итерации до <= <code>queue::back

...