How do you iterate backwards through an STL list?

前端 未结 5 1876
眼角桃花
眼角桃花 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条回答
  •  Happy的楠姐
    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()!

提交回复
热议问题