Adam Wulkiewicz wrote:
Hi Valentin,
Valentin Ziegler wrote:
Hi Adam,
return *begin(rng); For BidirectionalRange return *(--end(rng)); In 99% of all cases above implementations will work just fine. However, there may be rare cases where the lifetime of the reference is bound to the lifetime of the iterator:
[iterator.requirements.general] 9. Destruction of an iterator may invalidate pointers and references previously obtained from that iterator.
Thanks for pointing this one out.
So yes, iterator_wrapper/reference_proxy should be returned. With members: operator casting to reference and for non-mutable Range - copy assignment and probably move assignment, probably using Boost.Move move emulation. a remark: of course the assignment operators should be defined for mutable ranges or non-const iterators.
Is there a reason why move assignment isn't defined in proxies implemented in Boost.Iterator?
Btw, do you know the reason for this requirement? I can imagine that some iterator could store a temporary created from data gathered during the traversal. Or when dereferenced return some wrapper/proxy with a pointer to itself or one of its members. But this doesn't convince me. It should be a case when some external data or block of memory could "dissapear" after the destruction. So there could be a container e.g. loading data to the memory on the fly or some external memory mapped somehow. In this case the Iterator would behave like a shared_ptr<> since we'd be forced to track all Iterators pointing to the data which might "dissapear". Still it's too complicated for an Iterator. Is there some prosaic reason that I can't see?
Regards, Adam