我正在Windows和Mac之间编写一些跨平台代码.
如果list :: end()"返回一个迭代器来解决列表中最后一个元素之后的位置"并且可以在向前遍历列表时进行检查,那么向后遍历的最佳方法是什么?
此代码适用于Mac但不适用于Windows(不能超出第一个元素):
list::iterator iter = m_Objs.end(); for (iter--; iter!=m_Objs.end(); iter--)// By accident discovered that the iterator is circular ? { }
这适用于Windows:
list::iterator iter = m_Objs.end(); do{ iter--; } while (*iter != *m_Objs.begin());
是否有另一种可以在for循环中实现的向后遍历方法?
使用reverse_iterator而不是迭代器.使用rbegin()和rend()代替begin()和end().
如果您喜欢使用BOOST_FOREACH宏,另一种可能性是使用Boost 1.36.0中引入的BOOST_REVERSE_FOREACH宏.
扭转最好/最简单的方法迭代一个列表(如前所述)使用反向迭代rbegin /雷德.
不过,我想提一提,反向迭代器实现存储"当前"迭代器位置的off-by-一个(GNU的执行标准库中至少).
这样做是为了简化实现,以使范围相反具有相同的语义的范围内向前[开始,结束)和[rbegin,分割)
这意味着的是,解引用一个迭代涉及创建一个新的临时,然后递减到,每一次:
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; }
测试表明,对于循环体中使用的每个解引用,该解决方案要快〜5倍.
注意:上面的代码没有进行测试,因为std :: cout会成为瓶颈.
另请注意:'挂钟时间'差异为~5秒,std :: list大小为1000万个元素.实际上,除非您的数据大小那么大,只需坚持使用rbegin()rend()!
你可能想要反向迭代器.从记忆里:
list::reverse_iterator iter = m_Objs.rbegin(); for( ; iter != m_Objs.rend(); ++iter) { }
正如Ferruccio已经提到的那样,使用reverse_iterator:
for (std::list::reverse_iterator i = s.rbegin(); i != s.rend(); ++i)
这应该工作:
list::reverse_iterator iter = m_Objs.rbegin(); for (; iter!= m_Objs.rend(); iter++) { }