Re: Weird behaviour from std::list<>::reverse_iterator
Rune Allnor wrote:
On 25 Aug, 11:27, James Kanze <james.ka...@gmail.com> wrote:
On Aug 24, 7:53 pm, Rune Allnor <all...@tele.ntnu.no> wrote:
On 24 Aug, 19:34, Victor Bazarov <v.Abaza...@comAcast.net> wrote:
The semantics is clear: I have used reverse_iterators to work
my way from list.rbegin() to some item in the list. The
semantically simple call
list.erase(middle);
spawns a compiler error.
That's because there's no function list<>::erase which takes a
reverse iterator.
Your misconception is that *middle == *(middle.base()). It
isn't. The reverse iterator's 'base' iterator points to a
different value in the container. At least IME.
That's the opinion of the standard, too. In fact,
reverse_iterator<>::base is guaranteed to point to the element
after (in the original sequence) the one pointed to by the
reverse iterator. The reason for this is simple:
I can see the technical arguments why things are done
like this, but I can't see why these technicalities are
exposed to the users of the STL.
Whenever I, as *user* of the STL, uses a reverse iterator
to search for an item in a container, the natural semantics
of iterators (as a general concept, not C++ type) is to
manipulate the element in the container referenced by that
iterator. Not the element before. Not the element after.
Sure. And that's exactly what the program did: the call
list.erase(middle.base()) erased the element that middle.base() refers
to. The problem, as Victor said, is that that's not the element that
middle refers to. So the answer is: don't do that. middle.base() does
not do what you want; that's not its purpose. Look it up.
So from a semantic point of view, the obvious thing to
try is
std::list<T> list;
std::list<T>::reverse_iterator i = ...;
list.erase(i);
and then expect the item referenced by i to be erased.
Isn't that the philosophy behind the STL? That users
should only worry about semantics and not need to know
about implementation details?
The problem with that, of course, is that list::erase doesn't take a
reverse_iterator, so that code doesn't compile. You'd have the same
problem if you tried to use any other iterator type (except
list::iterator and list::const_iterator) here. And that's a legitimate
complaint. It's not legitimate to complain that an attempted workaround
that shouldn't work didn't work.
--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of
"The Standard C++ Library Extensions: a Tutorial and Reference"
(www.petebecker.com/tr1book)