你如何通过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)