Reusing a moved container?

C++C++11Move Semantics

C++ Problem Overview


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?

C++ Solutions


Solution 1 - C++

From section 17.3.26 of the spec "valid but unspecified state":

> 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.

Solution 2 - C++

The object being in a valid, but undefined state basically means that while the exact state of the object is not guaranteed, it is valid and as such member functions (or non member functions) are guaranteed to work as long as they don't rely on the object having a certain state.

The clear() member function has no preconditions on the state of the object (other than that it is valid, of course) and can therefore be called on moved-from objects. On the other hand for example front() depends on the container being not empty, and can therefore not be called, since it is not guaranteed to be non empty.

Therefore both ver2 and ver3 should both be fine.

Solution 3 - C++

I don't think you can do ANYTHING with a moved-from object (except destroy it).

Can't you use swap instead, to get all the advantages of moving but leave the container in a known state?

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionronagView Question on Stackoverflow
Solution 1 - C++Nicol BolasView Answer on Stackoverflow
Solution 2 - C++GrizzlyView Answer on Stackoverflow
Solution 3 - C++Ben VoigtView Answer on Stackoverflow