
2013/1/31 Paul Smith <pl.smith.mail@gmail.com>:
On Thu, Jan 31, 2013 at 9:24 AM, Antony Polukhin <antoshkka@gmail.com> wrote:
From theoretical point of view you are absolutely correct, and my example is lame. Moreover, current implementation of move assignment and move constructors for recursive_wrapper were implemented to model that behavior.
Just pointing out that move assignment is not affected by this discussion. Everything is already allocated so it's as efficient as a pointer swap.
Can not agree (variant makes some additional manipulations to guarantee non emptyness): void move_assign(recursive_wrapper<T>&& rhs) { ... // heap allocation in move constructor of recursive_wrapper // can be optimized away (see #7960) variant temp( detail::variant::move(rhs) ); // *this stores type different from recursive_wrapper<T>, // so it another call to move constructor of recursive_wrapper // will be made // Potential call to less effective move_assign implementation if // variant does not have fallback_type (+1 heap allocation and deallocation) variant_assign( detail::variant::move(temp) ); ... // heap deallocation in destructor of recursive_wrapper } With recursive_ptr this would be: void move_assign(recursive_ptr<T>&& rhs) { ... // swap ptrs // can be optimized away (see #7960) variant temp( detail::variant::move(rhs) ); // recursive_ptr move constructor does not throw, so // variant will use a fastest possible move assignment implementation // *this stores type different from recursive_wrapper<T>, // so it calls to move constructor of recursive_ptr // => swap ptrs variant_assign( detail::variant::move(temp) ); ... // destructors of temporaries will call delete on nullptrs // Whole function will be noexcept => variant can be move // assigned in STL containers (containers will use copy-assignments, // if this function can throw) } With recursive_ptr it is as efficient, as pointers swap! With recursive_wrapper it is multiple times slower. 2013/2/1 Dave Abrahams <dave@boostpro.com>:
on Thu Jan 31 2013, Paul Smith <pl.smith.mail-AT-gmail.com> wrote:
On Thu, Jan 31, 2013 at 9:24 AM, Antony Polukhin <antoshkka@gmail.com> wrote:
From theoretical point of view you are absolutely correct, and my example is lame. Moreover, current implementation of move assignment and move constructors for recursive_wrapper were implemented to model that behavior.
Just pointing out that move assignment is not affected by this discussion. Everything is already allocated so it's as efficient as a pointer swap.
Actually the correct semantics of move assignment is the same as "swap + clear" if there's an empty state. See http://cpp-next.com/archive/2009/09/your-next-assignment/
I recommend reading the whole article.
Oops, if move assignment shall be equal to "swap + clear", then the current implementations of recursive_wrappers move assign must be fixed (it just swaps). -- Best regards, Antony Polukhin