Is the destructor the only thing ever called on the RHS of a move ctor/assignment?

Viewed 54

My search-fu is good, but this is a difficult one to phrase correctly to find the answer. Basically, after a move ctor/assignment is invoked, is it guaranteed that the only thing that will ever be called on the RHS will be the destructor?

The reason I ask is that I have various things that (for sanity's sake) cannot be in an invalid state. But, far and away the most efficient move scheme would be to swap some stuff into them that the dtor can accept but nothing else could. Else, I have to allocate actual data, no matter how trivial, to keep the RHS in a valid state.

If the dtor is the only thing that will ever get called, then I can get maximum efficiency.

2 Answers

is it guaranteed that the only thing that will ever be called on the RHS will be the destructor?

No. It is well-formed to call member functions of a moved from object. The standard doesn't guarantee that a programmer won't do that.

As the implementor of a class, you can decide that some member functions must not be called on a moved from object, and thus can avoid for example allocating memory. Or, you can decide to not have such requirement. In general, having preconditions can allow more efficient implementation, while not having preconditions makes the class easier to use.

As the user of a class, you are responsible for following the preconditions of the member functions that you call (or member access). If a precondition of a function is that class is not in a moved from state, then don't break that precondition.

As a general rule, it's probably a good design to allow assignment operator to be called on a moved from object. That's what all (assignable) standard library classes do.


In short: There is no such guarantee by the standard, but you can impose such requirement on the user of the class. Just make sure it is well documented.

There’s nothing magic about moving from an object. After a move the object is still valid and if it’s not a temporary your code can call member functions on it and pass it to functions.

Just like any other object, and this is really the point of the question, the compiler won’t do anything to an object other than destroy it at the end of its lifetime. For a temporary object, that’s the end of the full statement that creates the object. For a named object, that’s the end of the scope in which the object is created.

Related