Boost logo

Boost :

From: David Abrahams (dave_at_[hidden])
Date: 2004-02-02 07:29:24

Robert Ramey <ramey_at_[hidden]> writes:

> Dave Abrahams wrote:
>>Robert Ramey wrote:
>>> it seems to me that it is implemented for non - random access
>>> iterators by incrementing one iterator until it equals the other and
>>> return the number of times the increment occured.
>>Yeah, it's a mistake. It shouldn't use distance, but operator-.
>>That way neither one of your subtractions would compile.
> From the documentation:
> counting_iterator requirements
> The Incrementable argument shall be Copy Constructible and
> Assignable.
> If iterator_category is convertible to forward_iterator_tag or
> forward_traversal_tag, the following must be well-formed:
> Incrementable i, j;
> ++i; // pre-increment
> i == j; // operator equal

What's your point?

> Suppose I had used a different iterator as a base - not
> an input iterartor but some kind of forward transveral iterator.
> Would that have been ok?

An input iterator is also OK, though it's destructive: input iterators
are single-pass, so when you increment them, you lose the data they
"refer" to.

A forward iterator is a more useful Incrementable type for

> Now if I understand correctly? the only difference between the single pass transveral
> and forward transversal is the ability to "rewind".

Not exactly; it's the ability to traverse the same set of elements
starting with a copy of the original iterator.

> As far as I can see the ability doesn't affect the requirement
> stated above.


> Are sure that the requirement isn't too strong.

In what way? It isn't requiring anything of your Incrementable type
that it didn't supply.

> The fact that it "accidently" works seems to suggest this.

The operator-() implementation was O(N), not O(1), so it did not
"work" at all as far as iterator requirements are concerned. You
just can't turn an input iterator into a random access iterator no
matter how hard you try.

> from the nomenclature, example, other "counting iterators", and common
> sense, I would expect an example such as the one I presented to
> function as I expected. And in fact it did in the previous release
> candidate.

You got "lucky". Or unlucky, depending on how you look at it.

> That is, its natural to expect the following to function
> std::fstream is;
> std::input_iterator begin(is), end();
> int filesize = end - begin;

I don't know what leads you to that expectation.
To begin with, there's no such thing as "std::input_iterator".
Secondly, you can't do it with any of the standard input_iterators
such as istream_iterator, istreambuf_iterator, et. al. Why would you
expect more from a wrapper over a standard input iterator?

> Can the design and implement (of off course document) be adjusted
> to permit this?

No way.

> If such a seemingly natural usage is not possible, it should be
> trapped at compile time (as you suggested)


> and the reason why it can't be supported described in the
> documentation.

I appreciate that any misconception like this can be said to indicate
a documentation failure, but really the input iterator requirements in
the standard and the single pass traversal iterator requirements in
the new iterator concepts are fairly clear. I don't think it's
reasonable to go out of our way to tell people *again* that only
random access iterators into the same sequence can be subtracted from
one another. Then we'd also have to mention +=, -=, [], and addition
and subtraction using the difference_type. Oh, and by the way, only
bidirectional iterators can be decremented. Repeating this
information for each specialized adaptor seems like too much.

Dave Abrahams
Boost Consulting

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