C++ 如何在STL列表中反向迭代?

C++ 如何在STL列表中反向迭代?,c++,list,stl,iterator,traversal,C++,List,Stl,Iterator,Traversal,我正在写一些Windows和Mac之间的跨平台代码 如果list::end()“返回一个迭代器,该迭代器可以寻址列表中最后一个元素之后的位置”,并且可以在向前遍历列表时进行检查,那么向后遍历的最佳方式是什么 此代码在Mac上工作,但在Windows上不工作(不能减量超过第一个元素): iterator iter=m_Objs.end(); for(iter--;iter!=m_Objs.end();iter--)//偶然发现迭代器是循环的? { } 这适用于Windows: list<D

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

如果list::end()“返回一个迭代器,该迭代器可以寻址列表中最后一个元素之后的位置”,并且可以在向前遍历列表时进行检查,那么向后遍历的最佳方式是什么

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

iterator iter=m_Objs.end(); for(iter--;iter!=m_Objs.end();iter--)//偶然发现迭代器是循环的? { } 这适用于Windows:

list<DVFGfxObj*>::iterator iter = m_Objs.end();
    do{
        iter--;
    } while (*iter != *m_Objs.begin());
iterator iter=m_Objs.end(); 做{ 国际热核聚变实验堆; }而(*iter!=*m_Objs.begin());
是否有另一种可以在for循环中实现的向后遍历方法?

使用
反向迭代器
而不是
迭代器
。 使用
rbegin()
&
rend()
而不是
begin()
&
end()


如果您喜欢使用宏,另一种可能是使用BOOST 1.36.0中引入的
BOOST\u REVERSE\u FOREACH
宏。

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

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

正如Ferruccio所提到的,使用反向迭代器:

for (std::list<int>::reverse_iterator i = s.rbegin(); i != s.rend(); ++i)
for(std::list::reverse_迭代器i=s.rbegin();i!=s.rend();++i)
这应该可以:

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

反向迭代列表的最佳/最简单方法是(如前所述)使用反向迭代器rbegin/rend

然而,我确实想提到的是,反向迭代器的实现将“当前”迭代器位置存储为1(至少在标准库的GNU实现上)

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

这意味着取消对迭代器的引用需要创建一个新的临时变量,然后每次都对其进行递减:

因此,取消对反向迭代器的引用比正常迭代器慢

但是,您可以使用常规双向迭代器自己模拟反向迭代,以避免此开销:

for ( iterator current = end() ; current != begin() ; /* Do nothing */ )
{
    --current; // Unfortunately, you now need this here
    /* Do work */
    cout << *current << endl;
}
for(迭代器current=end();current!=begin();/*什么都不做*/)
{
--current;//不幸的是,您现在需要这个
/*工作*/

迭代器和反向迭代器的文档几乎是一样的。迭代器是双向的,那么区别是什么?区别在于你仍然使用“++Iter”来增加迭代器,而不是“--Iter”.或者我错了吗?不,你是对的,向后递增有点奇怪,但也有意义。尽管反向迭代器似乎不必要,因为迭代器是双向的。反向迭代器的文档说它作用于一个反向列表;当然它不会先内部反转列表。@AlanKey:如果你知道你正在处理的是如果是一个列表,您可能只想减少普通迭代器。当您编写泛型代码时,反向迭代器是自己的-它不需要做任何特殊的事情来反向遍历集合-它只需要提供反向迭代器并非所有的“正向”迭代器都是“双向的”。这取决于集合类。谢谢,听起来不错。但是,如果假设迭代器是双向的,那么创建一个特殊的反向迭代器似乎也是一种浪费。它应该是“…>::反向迭代器iter=…”@AlanKley我认为您在问题中加入的for循环是好的。我认为它之所以有效,是因为.end()member函数返回一个sentinel值,该值被指定为最后一个元素的下一个指针的值,也是第一个元素上的上一个指针的值。哎呀,请重新阅读您的问题…在Windows上不起作用。我也在Mac上测试了代码。您的第一个示例只会是一个意外的实现(循环迭代器,与end()进行比较)会起作用。再看一遍,您可能只想用current=--end()初始化;并将增量步骤保留在for循环中。这还可以防止我上面的版本中没有的空数组。由于我还没有测试,我现在将保留原始数组。我认为这不会起作用,除非您也更改循环条件。否则,您将丢失第一项(如果
current==begin()
,则循环不会执行)for循环的第一行是递减的,所以我认为是的。只需编写一个快速测试来尝试它!无论如何,我不再认为这是使用此习惯用法的最佳方式,并且我最近运行的一些测试不再显示在完全优化的情况下反向迭代器的速度有显著提高。但是,值得注意的是,在e hood和相应的测试!我打算对你的评论发表评论,而不是答案,但因此删除了@部分。你答案中的代码工作得非常好,但是,我同意它可能不是最好的;)编辑:快速
  reference
  operator*() const
  {
_Iterator __tmp = current;
return *--__tmp;
  }
for ( iterator current = end() ; current != begin() ; /* Do nothing */ )
{
    --current; // Unfortunately, you now need this here
    /* Do work */
    cout << *current << endl;
}