假设我有两个向量,我将一个移到另一个,v1 = std::move(v2)
; 在此之后仍将v2
处于可用状态?
3 回答
从 n3290,17.6.5.15 库类型的移动状态 [lib.types.movedfrom]
- C++ 标准库中定义的类型的对象可以从 (12.8) 中移出。移动操作可以显式指定或隐式生成。除非另有说明,否则此类移出的对象应置于有效但未指定的状态。
由于状态是有效的,这意味着您可以安全地操作v2
(例如,通过分配给它,这将使它回到已知状态)。但是,由于它未指定,这意味着您不能依赖任何特定值,v2.empty()
只要它处于此状态(但调用它不会使程序崩溃)。
请注意,这个移动语义公理(“从对象中移出的对象处于有效但未指定的状态”)是所有代码(大多数时候)都应该努力实现的目标,而不仅仅是标准库组件。就像复制构造函数的语义应该是复制,但不是强制的。
不,它处于未指定的状态。
摘自open-std-org文章 -
.. move() 为其目标提供其参数的值,但没有义务保留其源的值。因此,对于向量,可以合理地期望 move() 将其参数保留为零容量向量,以避免复制所有元素。换句话说,移动是一种潜在的破坏性读取。
如果您想在移动后使用 v2,您需要执行以下操作:
v1 = std::move(v2);
v2.clear();
此时,v1 将具有 v2 的原始内容,并且 v2 将处于定义明确的空状态。这适用于所有 STL 容器(和字符串,就此而言),如果您正在实现自己的支持移动语义的类,您可能想要做类似的事情。
如果您对 STL 的特定实现确实使对象处于空状态,那么第二个 clear() 将基本上是无操作的。事实上,如果是这种情况,编译器在移动后消除 clear() 将是一种合法的优化。