C++ std::队列迭代
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1259099/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
std::queue iteration
提问by Hymanhab
I need to iterate over std::queue
.
www.cplusplus.com says:
我需要迭代std::queue
。www.cplusplus.com 说:
By default, if no container class is specified for a particular queue class, the standard container class template deque is used.
默认情况下,如果没有为特定队列类指定容器类,则使用标准容器类模板 deque。
So can I somehow get to the queue's underlying deque and iterate over it?
那么我可以以某种方式进入队列的底层双端队列并对其进行迭代吗?
采纳答案by CB Bailey
If you need to iterate over a queue
then you need something more than a queue. The point of the standard container adapters is to provide a minimal interface. If you need to do iteration as well, why not just use a deque (or list) instead?
如果您需要迭代 aqueue
那么您需要的不仅仅是队列。标准容器适配器的重点是提供最小的接口。如果您还需要进行迭代,为什么不直接使用双端队列(或列表)呢?
回答by Alexey Kukanov
While I agree with others that direct use of an iterable container is a preferred solution, I want to point out that the C++ standard guarantees enough support for a do-it-yourself solution in case you want it for whatever reason.
虽然我同意其他人的看法,即直接使用可迭代容器是首选解决方案,但我想指出的是,C++ 标准保证了对 DIY 解决方案的足够支持,以防您出于任何原因需要它。
Namely, you can inherit from std::queue
and use its protected member Container c;
to access begin() and end() of the underlying container (provided that such methods exist there). Here is an example that works in VS 2010 and tested with ideone:
也就是说,您可以继承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;
}
回答by StupidMe
you can save the original queue to a temporary queue. Then you simply do your normal pop on the temporary queue to go through the original one, for example:
您可以将原始队列保存到临时队列。然后,您只需在临时队列上执行正常的弹出操作以遍历原始队列,例如:
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();
}
At the end, the tmp_q will be empty but the original queue is untouched.
最后,tmp_q 将为空,但原始队列未受影响。
回答by Tejas Patil
One indirect solution can be to use std::deque instead. It supports all operations of queue and you can iterate over it just by using for(auto& x:qu)
. It's much more efficient than using a temporary copy of queue for iteration.
一种间接的解决方案是使用 std::deque 代替。它支持队列的所有操作,您只需使用for(auto& x:qu)
. 它比使用队列的临时副本进行迭代要高效得多。
回答by Chuck
Why not just make a copy of the queue that you want to iterate over, and remove items one at a time, printing them as you go? If you want to do more with the elements as you iterate, then a queue is the wrong data structure.
为什么不制作一份您想要迭代的队列的副本,并一次删除一个项目,并在您进行时打印它们?如果您想在迭代时对元素执行更多操作,那么队列就是错误的数据结构。
回答by Vaelus
while Alexey Kukanov's answermay be more efficient, you can also iterate through a queue in a very natural manner, by popping each element from the front of the queue, then pushing it to the back:
虽然阿列克谢·库卡诺夫的回答可能更有效,但您也可以以非常自然的方式遍历队列,方法是从队列的前面弹出每个元素,然后将其推到后面:
#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();
}
}
output:
输出:
0 1 4 9 16 25 36 49 64 81
回答by TimW
If you need to iterate a queue ... queue isn't the container you need.
Why did you pick a queue?
Why don't you take a container that you can iterate over?
如果您需要迭代队列......队列不是您需要的容器。
你为什么选择排队?
为什么不拿一个可以迭代的容器呢?
1.if you pick a queue then you say you want to wrap a container into a 'queue' interface: - front - back - push - pop - ...
1.如果你选择一个队列,那么你说你想把一个容器包装成一个“队列”界面: - 前 - 后 - 推 - 弹出 - ...
if you also want to iterate, a queue has an incorrect interface. A queue is an adaptor that provides a restricted subset of the original container
如果您还想迭代,则队列的接口不正确。队列是提供原始容器的受限子集的适配器
2.The definition of a queue is a FIFO and by definition a FIFO is not iterable
2. 队列的定义是 FIFO,根据定义,FIFO 是不可迭代的
回答by Shamiul Hasan Rumman
I use something like this. Not very sophisticated but should work.
我使用这样的东西。不是很复杂,但应该工作。
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.
}
It will work because when you pop something from q1, and push it into tem, it becomes the first element of tem. So, in the end tem becomes a replica of q1.
它会起作用,因为当您从 q1 弹出某些东西并将其推入 tem 时,它会成为 tem 的第一个元素。所以,最终 tem 变成了 q1 的复制品。
回答by johnmacd
std::queue
is a container adaptor, and you can specify the container used (it defaults to use a deque
). If you need functionality beyond that in the adaptor then just use a deque
or another container directly.
std::queue
是一个容器适配器,您可以指定使用的容器(默认使用 a deque
)。如果您需要适配器中的功能之外的功能,那么只需deque
直接使用一个或另一个容器。
回答by Dewfy
In short: No.
简而言之:没有。
There is a hack, use vector as underlaid container, so queue::front
will return valid reference, convert it to pointer an iterate until <= queue::back
有一个技巧,使用向量作为底层容器,因此queue::front
将返回有效引用,将其转换为指针并迭代直到 <=queue::back