你如何通过STL列表向后迭代?

我在Windows和Mac之间编写了一些跨平台的代码。

如果list :: end()“返回一个迭代器来处理列表中最后一个元素的后续位置”,并且可以在向前遍历列表时检查,那么向后遍历的最好方法是什么?

此代码在Mac上工作,但不在Windows上(不能超出第一个元素):

list<DVFGfxObj*>::iterator iter = m_Objs.end(); for (iter--; iter!=m_Objs.end(); iter--)// By accident discovered that the iterator is circular ? { } 

这在Windows上工作:

 list<DVFGfxObj*>::iterator iter = m_Objs.end(); do{ iter--; } while (*iter != *m_Objs.begin()); 

是否有另一种可以在for循环中实现的向后遍历?

使用reverse_iterator而不是迭代器。 使用rbegin()和rend()而不是begin()和end()。

另一种可能性是,如果你喜欢使用BOOST_FOREACHmacros,那么使用Boost 1.36.0中引入的BOOST_REVERSE_FOREACHmacros。

反转迭代器的最好/最简单的方法是(如前所述)使用反向迭代器rbegin / rend。

不过,我还是想提一下,反向迭代器是逐一存储“当前”迭代器的位置的(至less在标准库的GNU实现上)。

这样做是为了简化实现,以便反向范围具有与范围forward [begin,end)和[rbegin,rend]相同的语义。

这意味着取消引用迭代器涉及到创build一个新的临时对象,然后每次递减它:

  reference operator*() const { _Iterator __tmp = current; return *--__tmp; } 

因此, 解引用reverse_iterator比正常迭代器慢。

但是,您可以改为使用常规的双向迭代器来模拟反向迭代,避免了这种开销:

 for ( iterator current = end() ; current != begin() ; /* Do nothing */ ) { --current; // Unfortunately, you now need this here /* Do work */ cout << *current << endl; } 

testing显示这个解决scheme对于循环体中使用的每个解引用,速度快5倍。

注意:testing没有用上面的代码完成,因为std :: cout将是瓶颈。

另外请注意:“挂钟时间”差异是5秒,std :: list大小为1000万个元素。 所以,实际上,除非你的数据量很大,只要坚持rbegin()rend()!

你可能需要反向迭代器。 从记忆里:

 list<DVFGfxObj*>::reverse_iterator iter = m_Objs.rbegin(); for( ; iter != m_Objs.rend(); ++iter) { } 

这应该工作:

 list<DVFGfxObj*>::reverse_iterator iter = m_Objs.rbegin(); for (; iter!= m_Objs.rend(); iter++) { } 

正如Ferruccio所述,使用reverse_iterator:

 for (std::list<int>::reverse_iterator i = s.rbegin(); i != s.rend(); ++i)