Say I have two vectors and I move one unto the other, v1 = std::move(v2)
; will v2
still be in a usable state after this?

- 6,529
- 5
- 47
- 77

- 30,618
- 31
- 128
- 208
-
2This looks like a duplicate of http://stackoverflow.com/q/7027523/576911. See this answer: http://stackoverflow.com/questions/7027523/what-can-i-do-with-a-moved-from-object/7028318#7028318 to that question which discusses allowed operations in terms of preconditions. – Howard Hinnant Oct 28 '11 at 21:46
3 Answers
From n3290, 17.6.5.15 Moved-from state of library types [lib.types.movedfrom]
- Objects of types defined in the C++ standard library may be moved from (12.8). Move operations may be explicitly specified or implicitly generated. Unless otherwise specified, such moved-from objects shall be placed in a valid but unspecified state.
Since the state is valid, this means you can safely operate on v2
(e.g. by assigning to it, which would put it back to a known state). Since it is unspecified however, it means you cannot for instance rely on any particular value for v2.empty()
as long as it is in this state (but calling it won't crash the program).
Note that this axiom of move semantics ("Moved from objects are left in a valid but unspecified state") is something that all code should strive towards (most of the time), not just the Standard Library components. Much like the semantics of copy constructors should be making a copy, but are not enforced to.

- 34,649
- 6
- 70
- 114
-
+1, but the way it's written, it looks like you don't know if `v2` is empty after `v2 = std::vector{};` – Gabriel Oct 28 '11 at 20:41
No, it is left in an unspecified state.
Excerpt from open-std-org article -
.. move() gives its target the value of its argument, but is not obliged to preserve the value of its source. So, for a vector, move() could reasonably be expected to leave its argument as a zero-capacity vector to avoid having to copy all the elements. In other words, move is a potentially destructive read.

- 34,573
- 20
- 89
- 115
-
10It is left in an unspecified _but valid_ state. That is, you can still use the object in ways that only have the precondition that the object is valid. For example, you can call vector::clear() on that moved-from vector to get it into a known state, and then start inserting objects into it. – bames53 Oct 28 '11 at 15:05
-
4It __must__ be valid. Otherwise what would happen when the object goes out of scope. Most likely it won't have anything in its datastore, but whatever it is, it will be valid. – Damon Oct 28 '11 at 18:10
-
1There are multiple (abstract) levels of validity. As far as the language is concerned, the object after being moved is valid as far as the object still exists, its destructor can be called without causing undefined behavior, etc. The contract of the object, however, may be modified due to being moved. For example, the fact that a vector has become zero-sized (not having a capacity) is a valid C++ vector, but an object having a method that sets a particular element on the vector, without verifying the (now invalidated) assumption that the vector should have a particular size, becomes ... – rwong Sep 09 '16 at 22:20
-
1... becomes a disallowed operation (will cause UB). Such details shall be documented by the implementer of the object. The implementer should also provide a documented way to restore the usability of the object if it is ever needed. – rwong Sep 09 '16 at 22:22
If you want to use v2 after the move, you will want to do something like:
v1 = std::move(v2);
v2.clear();
At this point, v1 will have the original contents of v2 and v2 will be in a well-defined empty state. This works on all of the STL containers (and strings, for that matter), and if you are implementing your own classes that support move-semantics, you'll probably want to do something similar.
If your particular implementation of the STL actually DOES leave the object in an empty state, then the second clear() will be essentially a no-op. In fact, if this is the case, it would be a legal optimization for a compiler to eliminate the clear() after the move.

- 552
- 3
- 11