This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: Shouldn't advance be defined for ostream_iterator?
On Tue, Feb 03, 2004 at 10:29:55AM -0500, Neal D. Becker wrote:
> On Tuesday 03 February 2004 10:21 am, Jonathan Wakely wrote:
> > On Tue, Feb 03, 2004 at 10:07:09AM -0500, Neal D. Becker wrote:
> > > ostream_iterator has operator++ (nop), but no generic advance. I believe
> > > advance should be defined:
> > >
> > > namespace std {
> > > template<class T, class charT, class traits, typename dist_t>
> > > inline void advance (ostream_iterator<T,charT,traits>, dist_t) {}
> > > };
> >
> > std::advance() requires an InputIterator, whereas std::ostream_iterator
> > is a model of the OutputIterator concept, and the description from
> > http://www.sgi.com/tech/stl/OutputIterator.html says:
> >
> > [3] Assignment through an Output Iterator x is expected to alternate
> > with incrementing x, and there must be an assignment through x before
> > x is ever incremented. Any other order of operations results in
> > undefined behavior. That is: {*x = t; ++x; *x = t2; ++x} is
> > acceptable, but {*x = t; ++x; ++x; *x = t2;} is not.
> >
> > In other words, std::advance(x, 2) is not acceptable.
> >
>
> Thanks for the reply. Yes, I understand your argument, but the premise is
> that since ostream_iterator is a model of output_iterator, and since the
> requirements for output_iterator are X, therefore...
>
> Problem is the premise. It's true that ostream_iterator is considered a model
> of output_iterator, but that is really too restrictive. In fact, isn't it
> true that defining operator+= and advance for ostream_iterator would be
> perfectly harmless? Don't you agree that if operator++ is a nop, that
> logically operator+= should be also?
>
> I can demonstrate code where it would be useful.
Angelika Langer describes ostream_iterator as an "Immovable Output
Iterator" and states that they can't be advanced, and the concept of
"distance" between two ostream_iterators is meaningless:
The ostream_iterator in a way has dynamic semantics: The position of
the underlying stream changes whenever an object is assigned to the
de-referenced ostream_iterator. This position change is caused
automatically when the ostream_iterator's special assignment operator
uses the value type's stream inserter, and there is no task left for
the ostream_iterator's ++ operators.
[...]
The point is that incrementing an insert_iterator or an
ostream_iterator does not advance the iterator and therefore no other
iterator can ever be reached.
http://www.langer.camelot.de/Articles/C++Report/OutputIterators/OutputIterators.html)
I know this doesn't give a reason why it wouldn't work in practice, for
a less theoretical reason, libstdc++ has tried hard to remove all
non-standard extensions and adding this would allow non-standard and
non-portable code to compile - the standard doesn't allow it, so neither
does libstdc++.
jon
--
"Outside of a dog, a man's best friend is a book. Inside of a dog,
it's too dark to read."
-Groucho Marx