Search code examples
c++c++11move-semantics

Reusing a moved container?


What is the correct way to reuse a moved container?

std::vector<int> container;
container.push_back(1);
auto container2 = std::move(container);

// ver1: Do nothing
//container2.clear(); // ver2: "Reset"
container = std::vector<int>() // ver3: Reinitialize

container.push_back(2);
assert(container.size() == 1 && container.front() == 2);

From what I've read in the C++0x standard draft; ver3 seems to be the correct way, since an object after move is in a

"Unless otherwise specified, such moved-from objects shall be placed in a valid but unspecified state."

I have never found any instance where it is "otherwise specified".

Although I find ver3 a bit roundabout and would have much preferred ver1, though vec3 can allow some additional optimization, but on the other hand can easily lead to mistakes.

Is my assumption correct?


Solution

  • §17.3.26     valid but unspecified state     [defns.valid]

    an object state that is not specified except that the object’s invariants are met and operations on the object behave as specified for its type

    [ Example: If an object x of type std::vector<int> is in a valid but unspecified state, x.empty() can be called unconditionally, and x.front() can be called only if x.empty() returns false. — end example ]

    Therefore, the object is live. You can perform any operation that does not require a precondition (unless you verify the precondition first).

    clear, for example, has no preconditions. And it will return the object to a known state. So just clear it and use it as normal.