|
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
counting_iterator
> 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.
Correct.
> 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)
Done.
> 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 www.boost-consulting.com
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk