|
Boost : |
From: David Abrahams (dave_at_[hidden])
Date: 2004-04-21 06:39:40
Vladimir Prus <ghost_at_[hidden]> 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
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk