Re: problem with new iterators in 1.31 Release candidate # 2

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
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? Now if I understand correctly? the only difference between the single pass transveral and forward transversal is the ability to "rewind". As far as I can see the ability doesn't affect the requirement stated above. Are sure that the requirement isn't too strong. The fact that it "accidently" works seems to suggest this. 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. That is, its natural to expect the following to function std::fstream is; std::input_iterator begin(is), end(); int filesize = end - begin; Can the design and implement (of off course document) be adjusted to permit this? 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. Robert Ramey

Robert Ramey <ramey@rrsd.com> 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
participants (2)
-
David Abrahams
-
Robert Ramey