How do you iterate backwards through an STL list?

前端 未结 5 1870
眼角桃花
眼角桃花 2020-12-08 09:25

I\'m writing some cross-platform code between Windows and Mac.

If list::end() \"returns an iterator that addresses the location succeeding the last element in a list

相关标签:
5条回答
  • 2020-12-08 10:05

    Use reverse_iterator instead of iterator. Use rbegin() & rend() instead of begin() & end().

    Another possibility, if you like using the BOOST_FOREACH macro is to use the BOOST_REVERSE_FOREACH macro introduced in Boost 1.36.0.

    0 讨论(0)
  • 2020-12-08 10:12

    This should work:

    list<DVFGfxObj*>::reverse_iterator iter = m_Objs.rbegin();
    for (; iter!= m_Objs.rend(); iter++)
    {
    }
    
    0 讨论(0)
  • 2020-12-08 10:15

    As already mentioned by Ferruccio, use reverse_iterator:

    for (std::list<int>::reverse_iterator i = s.rbegin(); i != s.rend(); ++i)
    
    0 讨论(0)
  • 2020-12-08 10:16

    The best/easiest way to reverse iterate a list is (as already stated) to use reverse iterators rbegin/rend.

    However, I did want to mention that reverse iterators are implemented storing the "current" iterator position off-by-one (at least on the GNU implementation of the standard library).

    This is done to simplify the implementation, in order for the range in reverse to have the same semantics as a range forward [begin, end) and [rbegin, rend)

    What this means is that dereferencing an iterator involves creating a new temporary, and then decrementing it, each and every time:

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

    Thus, dereferencing a reverse_iterator is slower than an normal iterator.

    However, You can instead use the regular bidirectional iterators to simulate reverse iteration yourself, avoiding this overhead:

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

    Testing showed this solution to be ~5 times faster for each dereference used in the body of the loop.

    Note: Testing was not done with the code above, as that std::cout would have been the bottleneck.

    Also Note: the 'wall clock time' difference was ~5 seconds with a std::list size of 10 million elements. So, realistically, unless the size of your data is that large, just stick to rbegin() rend()!

    0 讨论(0)
  • 2020-12-08 10:28

    You probably want the reverse iterators. From memory:

    list<DVFGfxObj*>::reverse_iterator iter = m_Objs.rbegin();
    for( ; iter != m_Objs.rend(); ++iter)
    {
    }
    
    0 讨论(0)
提交回复
热议问题