
On 01/27/13 18:02, Joel de Guzman wrote:
On 1/28/13 12:18 AM, Dave Abrahams wrote:
on Sat Jan 26 2013, Joel de Guzman <djowel-AT-gmail.com> wrote:
On 1/26/13 7:58 AM, Dave Abrahams wrote:
I completely agree with the notion that a moved-from object simply should
not be used in any manner.
Well, that's just wrong, for the non-destructive move model used by the standard. The standard library relies on the ability to both assign and destroy moved-from elements. If you want destructive move, that's a whole research project. We on the committee who created rvalue references couldn't figure out how to make it work.
(The) ability to both assign and destroy? Is that all that it needs?
That's all the standard library will use. However, you still have to be honest about the variant's invariant: it must include the moved-from state.
Then we should be OK. A nulled recursive_wrapper can both be assigned and destroyed. It just can't do other things apart from that, such as get the underlying T& and call its member functions.
I am not familiar enough with the details of recursive_wrapper and how much of it is exposed to users to know whether any of this matters. You have to choose: either the addition of this moved-from state must not invalidate any previous guarantees upon which users may rely, OR you have to tell them that you're breaking backward-compatibility and document that the moved-from state is an "anti-precondition" for all the "other things apart from that."
Or you could invent a whole new concept of "invariant" that is allowed to be violated... but I really discourage that! :-)
I think we are OK!
Come to think of it, the situation is a lot like a "singular" iterator:
"Iterators can also have singular values that are not associated with any sequence. [snip] Results of most expressions are undefined for singular values; the only exceptions are destroying an iterator that holds a singular value, the assignment of a non-singular value to an iterator that holds a singular value, and, for iterators that satisfy the DefaultConstructible requirements, using a value-initialized iterator as the source of a copy or move operation."
Indeed, for a singular valued iterator, i, you can assign to i and destruct i, place i in a container, etc. You just cannot dereference i, access its underlying value through ->, compare i with another iterator, etc.
The same is true with a nulled recursive_wrapper.
[snip] What would a visitor do in this case? Currently, it requires a non-null recursive_wrapper, IIUC. If a nulled recursive_wrapper were allowed, would the visitors then need to supply: template<T> operator()(recursive_wrapper<T>const& rw) and the user would have to test rw::_p? -regards, Larry