This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]