重用移动的容器?

问题描述 投票:72回答:3

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

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

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

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

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

我的假设是否正确?

c++ c++11 move-semantics
3个回答
88
投票

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

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

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

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


10
投票

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

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

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


-8
投票

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

难道你不能使用swap,以获得移动的所有优点,但让容器处于已知状态?

© www.soinside.com 2019 - 2024. All rights reserved.