我需要遍历std::queue
。www.cplusplus.com说:
默认情况下,如果未为特定队列类指定容器类,则使用标准容器类模板双端队列。
那么我可以以某种方式到达队列的底层双端队列并对其进行迭代吗?
Answers:
如果您需要遍历a,queue
那么您需要的不仅仅是队列。标准容器适配器的重点是提供最小的接口。如果还需要进行迭代,为什么不只使用双端队列(或列表)呢?
queue
界面更丰富的东西,所以您应该选择具有合适界面的对象”。不管喜欢与否,迭代不是queue
界面的一部分,因此,如果要迭代,则需要选择其他内容。
queue
支持正向迭代器,但不反向反向迭代器,而不会增加我能想到的任何合理实现。我想CS101教授可能对此有所抱怨……
虽然我同意其他人的观点,即直接使用可迭代容器是首选解决方案,但我想指出,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;
}
deque
直接使用?
您可以将原始队列保存到临时队列。然后,您只需在临时队列上进行常规弹出操作即可遍历原始队列,例如:
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将为空,但原始队列未更改。
std::queue
似乎没有有.top()
法
std::queue
正确的方法是.front()
为什么不只复制要迭代的队列,然后一次删除一个项目,然后随手打印它们呢?如果要在迭代时对元素做更多的事情,那么队列是错误的数据结构。
malloc
/创建new
),请确保将其分配给free
/ delete
,否则会泄漏内存。
尽管Alexey Kukanov的答案可能更有效,但是您也可以通过非常自然的方式遍历队列,方法是从队列的前面弹出每个元素,然后将其推到后面:
#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
我用这样的东西。不是很复杂,但应该可以。
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的副本。
如果您需要迭代一个队列...队列不是您需要的容器。
你为什么选择队列?
为什么不带一个可以迭代的容器?
1.如果选择一个队列,则说要将容器包装到“队列”界面中:-正面-背面-推动-弹出-...
如果您还想迭代,则队列具有错误的接口。队列是提供原始容器的受限子集的适配器
2队列的定义是一个FIFO,根据定义FIFO是不可迭代的
std::queue
是容器适配器,可以指定使用的容器(默认使用deque
)。如果您需要适配器中没有的功能,则直接使用一个deque
或另一个容器即可。
deque
完全支持枚举。您可能会说,它deque
应该和它一样纯粹queue
,不支持迭代,如果要迭代它,则需要“更多”的东西。例如deque_enumerable
。虽然这是一个湿滑的斜坡,但我个人的感觉是queue
应该首先支持枚举。