【问题标题】:Why does C++ move semantics leave the source constructed?为什么 C++ 移动语义离开构建源?
【发布时间】:2016-02-01 00:07:30
【问题描述】:

在 C++11 中,引入了“移动语义”,通过两个特殊成员实现:移动构造函数和移动赋值。这两个操作都使 moved-from 对象被构造。

让源处于破坏状态不是更好吗?对已移动的对象,您唯一能做的不就是破坏它吗?

【问题讨论】:

  • “对于一个移动的对象,你能做的不就是破坏它吗?”从风格上讲,是的。从技术上讲,您可以将另一个对象移入其中。

标签: c++ c++11 move-semantics


【解决方案1】:

在“移动操作的宇宙”中有四种可能性:

target          source
  is            is left
----------------------------------------------------------
constructed <-- constructed  // C++11 -- move construction
constructed <-- destructed
assigned    <-- constructed  // C++11 -- move assignment
assigned    <-- destructed

这些操作中的每一个都是有用的! std::vector&lt;T&gt;::insert 单独可以使用前三个。虽然注意:

  • 第 2 和第 4 的源不应具有自动、静态或线程存储持续时间。源的存储持续时间必须是动态的,否则编译器将在已销毁的对象上调用析构函数。不,编译器无法(通常)跟踪对象是否已被移出:

X x1, x2;
if (sometimes)
{
    x1 = std::move(x2);
}
// Is x2 moved-from here?

  • 第 2 和第 4 可以分别由第 1 和第 3 模拟,只需在操作后手动调用源上的析构函数即可。

  • 第一个和第三个至关重要。 std::swapstd::sort 等算法经常需要这两种操作。这些算法不需要破坏它们的任何输入对象——只需改变它们的值。

有了这些知识,在 2001-2002 年的时间范围内,我将精力集中在两个操作上,因为这两个操作将对当时的 C++98 产生最大的(积极的)影响。我当时就知道,如果我不削减这个项目的雄心,它永远不会成功。即使被缩减,它也过于雄心勃勃而无法成功。

the original move semantics proposal 在标题为“破坏性移动语义”的部分下确认了这种缩减。

最后,我们只是因为太痛苦而放弃了 足够的收获。然而,目前的提案并不禁止 未来的破坏性移动语义。它可以在 除了本文中概述的非破坏性移动语义 如果有人希望携带火炬,请提出建议。

有关如何处理已移动对象的更多详细信息,请参阅https://stackoverflow.com/a/7028318/576911

【讨论】:

  • 有一个 C++1z 提议进行破坏性移动,目的是为了解决问题。
  • @Yakk-AdamNevraumont 你有关于这个提案的链接吗?我想要一些关于破坏性举动的细节。
  • @Yakk-AdamNevraumont:链接?
  • 霍华德,近年来有没有关于破坏性举动的活动?
  • 是的,但我没有密切关注它。但是没有论文就没有活动。所有论文都可以在这里找到:open-std.org/jtc1/sc22/wg21/docs/papers
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-12-16
  • 2021-08-29
相关资源
最近更新 更多