N4034: Destructive Move -- Pablo Halpern

A new WG21 paper is available. A copy is linked below, and will also appear in the next normal WG21 mailing. If you are not a committee member, please use the comments section below or the std-proposals forum for public discussion.

Document number: N4034

Date: 2014-05-27

Destructive Move

by Pablo Halpern


This paper proposes a function template for performing destructive move operations -- a type of move construction where the moved-from object, instead of being left in a “valid, but unspecified” state, is left in a destructed state. I will show that this operation can be made non-throwing in a wider range of situations than a normal move constructor, and can be used to optimize crucial operations, such as reallocations within vectors. An array version of the destructive move template is proposed specifically for moving multiple objects efficiently and with the strong exception guarantee.

The facilities described in this paper are targeted for a future library Technical Specification.

Add a Comment

Comments are closed.

Comments (2)

0 0

Zenju said on Jun 16, 2014 07:38 AM:

The paper seems to be motivated by its own incorrect sampe code:

// move constructor for a simple list type (no allocator support)
template <class T>
simple_list<T>::simple_list(simple_list&& other)
simple_list temp; // Default constructor might throw.
temp.swap(*this); // 'swap' never throws.

Yes, such a move-constructor would be wasteful. But no, that's not how it should be done in C++11.

Instead of needlessly creating a dummy variable and swapping, the move-constructor should just copy the handles and set the handles in "other" to nullptr. Then when the temporary is destructed, its destructor sees the null-handles and does nothing. Problem solved. Without needing a destructive move. Yes, there's still some inefficiency: The temporary's destructor needs an additional single check for null on a handle. But no, this is no serious perf problem that justifies additional C++ machinery to design away.
0 0

OleErikPeistorpet said on Apr 13, 2015 01:03 PM:

I think this would be a nice addition to the standard. I have been using something very similar for a while.

However, this proposal would not add much value without help from the compiler. Having to constantly specialize traits for your own types gets tiresome fast. And if you aren't careful when changing classes, it's easy to get in a situation where the requirements no longer hold, which could lead to nasty bugs.

Thinking about it, it should be easy for the compiler to get is_trivially_destructive_movable right for the vast majority of types, with no false positives. A type which is not trivially destructive movable would need a custom move or copy constructor to fix up pointers to its own members or update external observers, or be non-movable. So, if a type T has no user-defined copy or move operations (including deleted) and all the base classes and non-static members are trivially destructive movable (potentially by specialization of the trait), then we can safely conclude that T is also trivially destructive movable. I think.

It should also be possible for compilers to go further, but I don't have high hopes for that.