20

假设我有两个向量,我将一个移到另一个,v1 = std::move(v2); 在此之后仍将v2处于可用状态?

4

3 回答 3

28

从 n3290,17.6.5.15 库类型的移动状态 [lib.types.movedfrom]

  1. C++ 标准库中定义的类型的对象可以从 (12.8) 中移出。移动操作可以显式指定或隐式生成。除非另有说明,否则此类移出的对象应置于有效但未指定的状态。

由于状态是有效的,这意味着您可以安全地操作v2(例如,通过分配给它,这将使它回到已知状态)。但是,由于它未指定,这意味着您不能依赖任何特定值,v2.empty()只要它处于此状态(但调用它不会使程序崩溃)。

请注意,这个移动语义公理(“从对象中移出的对象处于有效但未指定的状态”)是所有代码(大多数时候)都应该努力实现的目标,而不仅仅是标准库组件。就像复制构造函数的语义应该是复制,但不是强制的。

于 2011-10-28T14:12:49.450 回答
6

不,它处于未指定的状态。

摘自open-std-org文章 -

.. move() 为其目标提供其参数的值,但没有义务保留其源的值。因此,对于向量,可以合理地期望 move() 将其参数保留为零容量向量,以避免复制所有元素。换句话说,移动是一种潜在的破坏性读取。

于 2011-10-28T13:52:06.790 回答
1

如果您在移动后使用 v2,您需要执行以下操作:

v1 = std::move(v2);
v2.clear();

此时,v1 将具有 v2 的原始内容,并且 v2 将处于定义明确的空状态。这适用于所有 STL 容器(和字符串,就此而言),如果您正在实现自己的支持移动语义的类,您可能想要做类似的事情。

如果您对 STL 的特定实现确实使对象处于空状态,那么第二个 clear() 将基本上是无操作的。事实上,如果是这种情况,编译器在移动后消除 clear() 将是一种合法的优化。

于 2018-02-05T21:18:31.763 回答