C++ std::队列迭代

C++ std::队列迭代,c++,queue,iteration,c++-standard-library,C++,Queue,Iteration,C++ Standard Library,我需要迭代std::queue。 www.cplusplus.com说: 默认情况下,如果没有为特定队列类指定容器类,则使用标准容器类模板deque 那么,我是否可以找到队列的底层数据并对其进行迭代?如果需要迭代队列,那么您需要的不仅仅是队列。标准容器适配器的要点是提供一个最小的接口。如果您也需要进行迭代,为什么不使用一个deque(或list)来代替呢?简言之:不 有一种方法,使用vector作为底层容器,因此queue::front将返回有效引用,将其转换为指针,直到如果需要迭代队列。。。队

我需要迭代
std::queue
。 www.cplusplus.com说:

默认情况下,如果没有为特定队列类指定容器类,则使用标准容器类模板deque


那么,我是否可以找到队列的底层数据并对其进行迭代?

如果需要迭代
队列
,那么您需要的不仅仅是队列。标准容器适配器的要点是提供一个最小的接口。如果您也需要进行迭代,为什么不使用一个deque(或list)来代替呢?

简言之:不


有一种方法,使用vector作为底层容器,因此
queue::front
将返回有效引用,将其转换为指针,直到如果需要迭代队列。。。队列不是您需要的容器。
你为什么要排队
为什么不使用一个可以迭代的容器呢


1.如果选择队列,则表示要将容器包装到“队列”界面中: -正面 -背 -推 -流行音乐 -

如果您还希望迭代,则队列的接口不正确。队列是提供原始容器的受限子集的适配器


2.定义队列是FIFO,根据定义,FIFO不是可迭代的< /P> < P>。而我同意其他人,直接使用迭代容器是一个优选的解决方案,我想指出C++标准保证了一个自己动手解决方案的足够支持,不管您出于什么原因想要它。 也就是说,您可以从

std::queue
继承并使用其受保护的成员
容器c
访问底层容器的begin()和end()(前提是存在这样的方法)。以下是一个适用于VS 2010的示例:

#包括
#包括
#包括
模板
类iterable_队列:公共标准::队列
{
公众:
TypeDefTypeName容器::迭代器迭代器;
typedef typename容器::常量迭代器常量迭代器;
迭代器begin(){返回此->c.begin();}
迭代器end(){返回此->c.end();}
常量迭代器begin()常量{返回此->c.begin();}
const_迭代器end()const{返回此->c.end();}
};
int main(){
iterable_队列int_队列;

for(int i=0;i
std::queue
是一个容器适配器,您可以指定使用的容器(默认情况下使用
deque
)。如果您需要适配器中除此之外的功能,则直接使用
deque
或另一个容器。

为什么不只是复制要迭代的队列,然后一次删除一个项目,边打印边打印?如果您想在迭代时对元素进行更多操作,那么队列是错误的数据结构re.

您可以将原始队列保存到一个临时队列。然后您只需在临时队列上执行常规的pop操作,即可查看原始队列,例如:

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();
} 
queue tmp\u q=original\u q;//将原始队列复制到临时队列
而(!tmp_q.empty())
{
q_元素=tmp_q.front();

std::cout我用的是这样的东西。不是很复杂,但应该有用

    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. 
    }
tem;
而(!q1.empty())//q1是您的初始队列。
{
intu=q1.front();
//使用此值执行您需要执行的操作。
q1.pop();
tem.push(u);
}
而(!tem.empty())
{
int u=tem.front();
tem.pop();
q1.推(u);//将其放回原始队列。
}
这将起作用,因为当您从q1中弹出某个内容并将其推入tem时,它将成为tem的第一个元素。因此,最终tem将成为q1的副本。

虽然效率可能更高,但您也可以以非常自然的方式迭代队列,方法是从队列前面弹出每个元素,然后将其推到后面:

#包括
#包括
使用名称空间std;
int main(){
//填充队列
队列q;
对于(int i=0;i<10;++i)q.push(i);
//遍历队列
对于(大小i=0;icout一个间接的解决方案是使用std::deque。它支持队列的所有操作,您只需使用for(auto&x:qu)的
就可以对其进行迭代
。这比使用队列的临时副本进行迭代要有效得多。

您也可以直接使用deque,它包含所有必要的方法作为队列,但也支持迭代。虽然我知道您的意思,但我一直不喜欢这种说法“队列以外的东西”。带有枚举的队列仍然是一个队列…另外,请观察
deque
如何恰好完全任意地支持枚举。您也可以认为
deque
应该与
queue
一样纯粹,不支持迭代,如果您想迭代它,那么您需要“更多”;例如,
dequeue_enumerable
。虽然这是一个滑坡,但我个人的感觉是,
queue
应该首先支持枚举。@romkyns:如果我重新表述一下会更好吗:“您需要比
队列
接口更丰富的接口,因此您应该选择具有合适接口的对象"。不管你喜不喜欢,迭代不是
队列
接口的一部分,所以如果你想要迭代,你需要选择其他东西。因为我的用例需要一个队列,但为了调试和日志记录的目的,我需要将其转储。假设海报不知道他们在做什么,这通常是没有建设性的。@RomanStarkov-似乎应该这样做ld可以让
queue
支持前向迭代器,但不支持反向迭代器,而不会给我能想到的任何合理实现带来负担。我想CS101 Prof可能会对此抱怨…@EML-My n
    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. 
    }
0 1 4 9 16 25 36 49 64 81