reverse_iterator::base, possible bug?

E

Eric Twietmeyer

Hello,

In playing with a reverse_iterator issue today, I realized that I could use
its base() method to get at the underlying iterator. However, I realized
that in the implementation shipping with VC7.1 the base() method returns
"current", the internal iterator object, but that "current" iterator is
always set up to be "pointing" at the element AFTER the one you think.

For instance in <xutility> operator*() is defined as:

reference operator*() const
{
_RanIt _Tmp = current;
return *--_Tmp;
}

So if one uses the base() method you get something unexpected, i.e. you get
"current", which must be decremented before dereferenced to get the element
value you want.

At least, it seems unexpected if one reads section 16.3.2 of Stroustrup C++
3rd Ed. (page 445 in soft cover version). There he has an example of a
find_last method that reads:

template <class C>
typename C::iterator find_last( const C& c, typename C::value_type v )
{
return find_first( c.rbegin(), c.rend(), v ).base();
}

which seems to imply that base() should return the iterator to the element
found by find_first, not the one after the element found.

Basically, the question is: Is the shipping implementation correct? I
assume it is, but then I don't understand how the example from Stroustrup is
supposed to work.

Thanks,

-Eric Twietmeyer
 
D

Doug Harrison [MVP]

Eric said:
Hello,

In playing with a reverse_iterator issue today, I realized that I could use
its base() method to get at the underlying iterator. However, I realized
that in the implementation shipping with VC7.1 the base() method returns
"current", the internal iterator object, but that "current" iterator is
always set up to be "pointing" at the element AFTER the one you think.

For instance in <xutility> operator*() is defined as:

reference operator*() const
{
_RanIt _Tmp = current;
return *--_Tmp;
}

So if one uses the base() method you get something unexpected, i.e. you get
"current", which must be decremented before dereferenced to get the element
value you want.

That's the way reverse_iterator::base is supposed to work.
At least, it seems unexpected if one reads section 16.3.2 of Stroustrup C++
3rd Ed. (page 445 in soft cover version). There he has an example of a
find_last method that reads:

template <class C>
typename C::iterator find_last( const C& c, typename C::value_type v )
{
return find_first( c.rbegin(), c.rend(), v ).base();
}

which seems to imply that base() should return the iterator to the element
found by find_first, not the one after the element found.

Basically, the question is: Is the shipping implementation correct? I
assume it is, but then I don't understand how the example from Stroustrup is
supposed to work.

That was fixed in an erratum:

Errata for 5th printing of The C++ Programming Language
http://www.research.att.com/~bs/3rd_printing6.html
 
C

Carl Daniel [VC++ MVP]

Eric said:
Thanks for the pointer! I was quite confused by this. I'll try to
look in the
standard and see what it says about "base". Thanks again.

Also look in Scott Meyer's "Effective STL" for a lengthy discussion of the
bizzare behavior of reverse_iterator.

-cd
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top