重用移动的容器?

时间:2012-02-06 23:18:54

标签: c++ c++11 move-semantics

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

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似乎是正确的方法,因为移动后的对象在

  

“除非另有规定,否则应放置此类移动物品   处于有效但未指定的状态。“

我从来没有找到任何“以其他方式指定”的实例。

虽然我发现ver3有点回旋并且会有更多首选ver1,虽然vec3可以允许一些额外的优化,但另一方面很容易导致错误。

我的假设是否正确?

3 个答案:

答案 0 :(得分:88)

从规范“有效但未指明的状态”的第17.3.26节:

  

未指定的对象状态,除了满足对象的不变量,并且对象上的操作按其类型指定的行为[示例:如果类型为x的对象std::vector<int>处于有效状态但未指明的状态,x.empty()可以   无条件调用,只有x.front()返回false时才能调用x.empty()。 - 例子]

因此,对象是实时的。您可以执行任何不需要前置条件的操作(除非您先验证前置条件)。

例如,

clear没有先决条件。它会将对象返回到已知状态。所以只需清除它并正常使用它。

答案 1 :(得分:10)

处于有效但未定义状态的对象基本上意味着虽然不保证对象的确切状态,但它是有效的,因此保证了成员函数(或非成员函数)只要他们不依赖具有某种状态的物体就能工作。

clear()成员函数对对象的状态没有先决条件(当然除了它是有效的),因此可以在移动的对象上调用。另一方面,例如front()取决于容器不为空,因此不能被调用,因为它不能保证非空。

因此ver2和ver3都应该都没问题。

答案 2 :(得分:-8)

我不认为你可以使用移动对象做任何事情(除了销毁它)。

您是否可以使用swap来获得移动的所有优点,但将容器置于已知状态?