 # Boost :

From: John E. Potter (jpotter_at_[hidden])
Date: 2001-07-07 13:55:41

On Fri, 6 Jul 2001, Douglas Gregor wrote:

> On Friday 06 July 2001 12:14, you wrote:

> > Iterators
> > are used in algorithms to iterate over (pseudo)sequences. For
> > input iterators, increment must move the iterator and dereference
> > must not. Dereferencing an input iterator twice must give the
> > same element of the (pseudo)sequence. Whether that element has
> > a stable value has nothing to do with the iterator.
>
> From which stated input iterator requirements (i.e., clause/table in
> the C++ standard) do you conclude this?

The increment must move the iterator has been demonstrated by the
use of the distance algorithm on input iterator.

Ok, I'll play the game. 24.1 Iterators are a generalization of
pointers ...

Dereferencing a pointer does not modify the pointer.

Now compare table 72 to tables 73-76. Notice that the formats are
different. Something funny happened on the way to the standard.
Table 72 had a column removed. Is this the correct format and
time did not permit changing the others? Are the others correct
and this is an editorial error? Did the left hand not know what
the right hand was doing?

Look at tables 73 and 74. ++r ... &++r == &r. Table 75. --r ...
&--r == &r. Table 72. ++r ... duh. Is t = *++r equivalent to
++r; t = *r for input iterators? Following b = ++a, is a == b?

Look at table 74. *a ... a == b implies *a == *b. This is obviously
not an implication that T must be equality comparable. Should it
read a == b implies &*a == &*b? Or *a is equivalent to *b? Can
you find anything in the standard which shows if a == b that after
*a = t it is still true that a == b?

Now table 72. a == b implies *a is equivalent to *b. You claim
that this allows side effects which would make T is equality
comparable and a == b implies *a == *b invalid. It can't be
changed to a == b implies &*a == &*b because *r could return an
rvalue. Even for istream_iterator which is buffered and *r returns
a T const&, a == b would not imply that &*a == &*b. The standard
neither requires nor prohibits this. Amusingly, it would be true that
&*r == &*++r.

So, there are lots of things in clause 24 which are less than clear.

I think that your motivation for the subject iterator is the best
example of why *r is stable. There are several algorithms which
return input iterators and they are only useful when that is true.
The STL is algorithms which work with iterators which have the
desired properties. Maybe clause 24 is a mess, but the intent is
clear.

Finally, look at the first sentence of clause 24. This clause
describes iterators over containers, streams, and stream buffers.
If you have something which is not an iterator over one of them,
this clause does not apply and it is not any kind of iterator.
I can accept an iterator over a virtual container, but that implies
a stable operator*. Looking at a (virtual) container does not
change the container nor the iterator. Even output iterators have
a stable operator* which does nothing observable.

John