
On 01/21/13 07:39, Antony Polukhin wrote:
Current implementation of recursive_wrapper move constructor is not optimal:
recursive_wrapper<T>::recursive_wrapper(recursive_wrapper&& operand) : p_(new T(std::move(operand.get()) )) { }
During descussion were made following proposals: [snip] III: Make recursive_wrapper and variant cooperate, enable move for varinat in the presence of recursive_wrappers only when there is at least one type that is nothrow-default-constructible, regardless of whether it's current. It is easyer to understand by example: typedef variant<int, recursive_wrapper<foo>> V; V v1( std::move(v2) ); This move-constructs v1 from v2 and leaves int() into v2. + good performance + provides noexcept guarantee for rcursive_wrapper + does not adds an empty state - optimization won't trigger if varinat has no type with trivial default constructor - hard to implement - user may be obscured by the fact, that v2 from the example now contains int
[snip] What about III except the moved-from variant's which() method returns -2 (or some other "signal" value) signalling the object has been moved from? The moved-from variant's destructor and assign operators would check the which() value (as, I assume, they now do) and behave accordingly (the destructor would simply do nothing except recover the buffer memory). The user, using the example you provide above, would be, I believe, *less* obscured by this than v2 containing an int, because now v2 would contain some "signal" value, such as boost::blank which the user would realize meant something unusual had happened. Implementation, AFAICT, would be very simple and there would be no need to check if the variant had no type with trivial default constructor because boost::blank *does* have a trivial default constructor. The one downside I see is this might break existing code. Of course I'm probably missing something, and any enlightenment would be appreciated. -regards, Larry