移动会使对象处于可用状态吗?

发布于 2024-12-12 18:19:01 字数 89 浏览 5 评论 0原文

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

Say I have two vectors and I move one unto the other, v1 = std::move(v2); will v2 still be in a usable state after this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梦里°也失望 2024-12-19 18:19:02

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

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

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

请注意,移动语义的这条公理(“从对象中移动的对象保持有效但未指定的状态”)是所有代码(大多数时候)都应该努力实现的目标,而不仅仅是标准库组件。与复制构造函数的语义非常相似,应该进行复制,但不强制这样做。

From n3290, 17.6.5.15 Moved-from state of library types [lib.types.movedfrom]

  1. Objects of types defined in the C++ standard library may be moved from (12.8). Move operations may be explicitly specified or implicitly generated. Unless otherwise specified, such moved-from objects shall be placed in a valid but unspecified state.

Since the state is valid, this means you can safely operate on v2 (e.g. by assigning to it, which would put it back to a known state). Since it is unspecified however, it means you cannot for instance rely on any particular value for v2.empty() as long as it is in this state (but calling it won't crash the program).

Note that this axiom of move semantics ("Moved from objects are left in a valid but unspecified state") is something that all code should strive towards (most of the time), not just the Standard Library components. Much like the semantics of copy constructors should be making a copy, but are not enforced to.

不知在何时 2024-12-19 18:19:02

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

摘自open-std-org文章-

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

No, it is left in an unspecified state.

Excerpt from open-std-org article -

.. move() gives its target the value of its argument, but is not obliged to preserve the value of its source. So, for a vector, move() could reasonably be expected to leave its argument as a zero-capacity vector to avoid having to copy all the elements. In other words, move is a potentially destructive read.

心在旅行 2024-12-19 18:19:02

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

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

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

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

If you want to use v2 after the move, you will want to do something like:

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

At this point, v1 will have the original contents of v2 and v2 will be in a well-defined empty state. This works on all of the STL containers (and strings, for that matter), and if you are implementing your own classes that support move-semantics, you'll probably want to do something similar.

If your particular implementation of the STL actually DOES leave the object in an empty state, then the second clear() will be essentially a no-op. In fact, if this is the case, it would be a legal optimization for a compiler to eliminate the clear() after the move.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文