重复使用移动的容器?

重用移动的容器的正确方法是什么?

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);

从我在 C + + 0x 标准草案中读到的内容来看,ver3似乎是正确的方法,因为 move 之后的对象在

”除非另有说明,否则这些移离的物体应放置在 处于有效但未指明的状态”

我从来没有发现有任何实例是“另有说明”的。

虽然我觉得 vec3有点迂回,而且更喜欢 v1,虽然 vec3可以允许一些额外的优化,但是另一方面很容易导致错误。

我的假设正确吗?

13626 次浏览

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?

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.

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.