Boost logo

Boost :

From: John E. Potter (jpotter_at_[hidden])
Date: 2001-08-10 13:57:02

On Fri, 10 Aug 2001, Douglas Gregor wrote:

> Constructing input iterators based on what I believe are the intended
> semantics (and I think are reinforced by the definitions of istream_iterator
> and istreambuf_iterator) is _hard_.

It does not seem difficult to me. Istream iterators must be buffered
and operator* must be stable. The only problem is making *it++ work.
The standard gives two examples using an internal buffer and a proxy.

> For cases where dereferencing may cause
> side effects it is _very_ painful because

You are violating the concept of an iterator being a pointer into
some sequence. I think that the designers of the STL understood
this problem and created generators as an alternative to iterators.

> struct some_input_iterator {
> boost::shared_ptr< std::pair<T, bool> > value;
> some_input_iterator() : value(new make_pair(T(), false)) {}

Is this an end iterator? If not, how do I create a range? Algorithms
need ranges and iterators exist for algorithms.

> some_input_iterator(const some_input_iterator& other) :
> value(other.value) {}

This is the copy ctor. If the above is an end iterator, how do I
get a begin iterator?

> some_input_iterator& operator++()
> {
> value.reset(new make_pair(T(), false)); return *this;
> }

Assuming that I can get a begin and end iterator, does the distance
algorithm give the correct result? Does it even terminate?

I really think the problem is in trying to claim that something
which does not iterate through a sequence is an iterator. Having
one of those things may be quite useful; however, there is no
need to try to distort the iterator concept to make it fit or
to claim that it is an iterator.

Another support for stable operator* is the merge algorithm. Do
you think that the standard intended to require internal buffers
for the two ranges? I would prefer avoiding the extra copy.


Boost list run by bdawes at, gregod at, cpdaniel at, john at