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