tags:

views:

676

answers:

3

I am trying to do something like this:

for ( std::list< Cursor::Enum >::reverse_iterator i = m_CursorStack.rbegin(); i != m_CursorStack.rend(); ++i )
{
    if ( *i == pCursor )
    {
        m_CursorStack.erase( i );
        break;
    }
}

However erase takes an iterator and not a reverse iterator. is there a way to convert a reverse iterator to a regular iterator or another way to remove this element from the list?

+8  A: 

After some more research and testing I found the solution. Apparently according to the standard [24.4.1/1] the relationship between i.base() and i is:

&*(reverse_iterator(i)) == &*(i - 1)

(from a Dr. Dobbs article):

alt text

So you need to apply an offset when getting the base(). Therefore the solution is:

m_CursorStack.erase( --(i.base()) );
0xC0DEFACE
Thanks for pointing out that erase(i.base()) is wrong -- I have some code that does that and works, and now I don't know why! :(
Dan
You should take note of a bit more of the article you cited - to be portable the expression should be `m_CursorStack.erase( (++i).base())` (man, doing this stuff with reverse iterators makes my head hurt...). It should also be noted that the DDJ article is incorporated into Meyer's "Effective STL" book.
Michael Burr
+1  A: 

While using the reverse_iterator's base() method and decrementing the result works here, it's worth noting that reverse_iterators are not given the same status as regular iterators. In general, you should prefer regular iterators to reverse_iterators (as well as to const_iterators and const_reverse_iterators), for precisely reasons like this. See Doctor Dobbs' Journal for an in-depth discussion of why.

Adam Rosenfield
A: 

Please note that m_CursorStack.erase( (++i).base()) may be a problem if used in a for loop (see original question) because it changes the value of i. Correct expression is m_CursorStack.erase((i+1).base())

Andrey