
Vladimir Prus <ghost@cs.msu.su> writes:
There's a bug report on sourceforge:
https://sourceforge.net/tracker/index.php?func=detail&aid=937606&group_id=7586&atid=107586
which boils down to the fact that
directory_iterator it(...);
path p = *it++;
does not work correctly. The exact problem is that the above line return a copy of the iterator, and increments 'it', but both iterators have shared_ptr to the same internal structure, so by time user deferences the copy, it gets the next file in the directory.
The filesystem lib sources contain the following comment:
The *r++ requirement doesn't appear to apply to the new single_pass_traversal category Thus I'm leaving the proxy out pending confirmation from the N1477 authors
I'm kinda surprised that nobody asked us about that problem; we can't confirm something we don't know about!
I'm not sure I understand that. It seems that *r++ should work, since signle pass iterator requires that r++ should work and return object of type X (call it r2), and the reabable iterator requires that *r2 should work. Am I wrong?
The question is, what are the semantics? Input iterator requirements say: Expression Type Semantics ---------- ---- ------------------------------ (void)r++ equivalent to (void)++r *r++ T { T tmp = *r; ++r; return tmp; } But we don't have anything similar in the new concepts. I guess that's because we're trying to orthogonalize access and traversal, but that may not be possible in this case. If we don't define the semantics of *r++, a single-pass iterator is free to implement the semantics of *r++ as equivalent to *++r, which is what directory_iterator is doing. I'm sure directory_iterator is reporting that its category is input_iterator_tag, so I guess we have a problem in the new iterator concepts and in the iterator_facade implementation here.
And BTW, don't the above requirements
Which ones?
mean r++ cannot return a proxy object, but only a real copy of the iterator?
The input iterator requirements seem to imply that, for true single-pass sequences like streams, either: a. the iterator can store a copy of its value_type so that the iterator returned from r++ can still return the 'tmp' value indicated above when dereferenced b. the iterator can track whether an iterator returned from a post-increment is "active and not yet dereferenced" case b. is interesting; it would mean that operator++(int) can set a flag telling the iterator to consume another value before dereferencing. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com