c++ 如何在STL列表中向后遍历?

ahy6op9u  于 11个月前  发布在  其他
关注(0)|答案(5)|浏览(87)

我正在写一些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循环中实现的反向遍历方法?

i1icjdpr

i1icjdpr1#

使用reverse_iterator代替iterator。使用rbegin()rend()代替begin()end()
如果你喜欢使用BOOST_FOREACH宏,另一种可能性是使用Boost 1.36.0中引入的BOOST_REVERSE_FOREACH宏。

lyr7nygr

lyr7nygr2#

最好的/最简单的方法是(如前所述)使用反向迭代器rbegin/rend。
然而,我确实想提到的是,反向迭代器是通过存储“当前”迭代器位置来实现的(至少在标准库的GNU实现中是这样)。
这样做是为了简化实现,以使反向范围具有与正向范围[开始,结束)和[r开始,结束)相同的语义。
这意味着解引用迭代器涉及到创建一个新的临时变量,然后递减它,* 每次 *:

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可能是瓶颈。
另请注意:在std::list大小为1000万个元素的情况下,“挂钟时间”差约为5秒。因此,实际上,除非您的数据大小很大,否则只需坚持使用rbegin()rend()!

klsxnrf1

klsxnrf13#

你可能需要反向迭代器。从内存:

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

字符串

n1bvdmb6

n1bvdmb64#

正如Ferruccio已经提到的,使用reverse_iterator:

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

字符串

oalqel3c

oalqel3c5#

这应该可以:

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

字符串

相关问题