std::vector move assignment vs move construction: why is the state of 'other' not consistent?
Asked Answered
V

1

6

For move construction:

After the move, other is guaranteed to be empty(). 1

For move assignment, the oft-quoted:

other is in a valid but unspecified state afterwards. 2

Why is the state of other different in these two cases?

Verda answered 24/2, 2022 at 6:2 Comment(0)
C
9

There are 2 popular ways to implement move in containers like vector that internally hold a pointer to the data:

  • you can empty this, then copy the pointer (and size and capacity) from other to this and then set other members to nullptr/zero
  • you can swap the data members (the pointers, size and capacity).

The standard wants to leave leeway to implementations to do either. These guarantees are the strongest guarantees it can make while allowing either methods of implementation:

  • move constructor:

    • 1st method: leaves other in empty state
    • 2st method (swap): leaves other in empty state
  • move assignment:

    • 1st method: leaves other in empty state
    • 2st method (swap): leaves other as a copy of initial this
Charcuterie answered 24/2, 2022 at 6:41 Comment(3)
So for (1) the "and then empty other" step is done to honor the "valid but unspecified" state requirement.Verda
@JarrodSmith yes. A moved from object must be in a valid but unspecified state. That is a requirement throughout all the standard library.Charcuterie
Notably method 2 implicitly supports self-assignment. Either way is funky with self-construction (a.k.a. std::vector<foo> vec = std::move(vec);, which hits -Wmaybe-uninitialized for me)Bellerophon

© 2022 - 2025 — McMap. All rights reserved.