为什么不用std ::在C ++中移动一个关键字?

时间:2016-09-30 16:46:15

标签: c++11 move-semantics

显然,在C ++ 11中,移动语义/ r值引用是非常需要的补充。但是,有一件事总是让我感到困惑,那就是std :: move。 std :: move的目的是将l值转换为r值。然而,编译器非常乐意让你继续使用该值作为l值,并且你可以在运行时发现你搞砸了。

似乎错过了将move(或其他名称)定义为关键字(类似于* _cast)的机会,实际上让编译器明白引用的值不能再用作l值。我确信有一些实施工作可以做到这一点,但是有没有一个根本原因可以解决这个问题呢?

1 个答案:

答案 0 :(得分:2)

在C ++中,移动的对象仍然是对象。它们可以使用。它们通常处于确定的状态。

当你愿意扼杀胆量时,你可以做一些优化。从一个物体中出来并在别处使用它。 C ++委员会决定这些优化应该在少数情况下隐式和自动完成;通常情况下,已经允许省略,但无论出于何种原因它都不会工作。

然后,添加了明确执行此操作的功能。使这个操作结束其右手边的生命周期会使C ++的生命周期规则复杂化到极端程度;而不是这样做,他们注意到它们可以非常高效而不会使C ++的生命周期规则复杂化,并使它们完全按原样保留。

事实证明,这有一些瑕疵;在这种程度上,C ++ 20可能会添加一些"移动和销毁源"操作。特别是,如果你能一举移动并摧毁震源,那么许多类似移动构造的操作就更容易写出来。

实际上让它改变自动存储变量的生命周期并不在卡片中。即使描述这种变化如何起作用,更不用说确保它不会破坏任何可怕的东西,这将是一个挑战。

为什么总是发生的一个简单例子可能不会很好:

Foo foo;
if (some_condition) {
  bar = std::move(foo);
}

foo的生命周期现在是some_condition的函数?你要么必须用这种结构禁止上述内容,要么陷入疯狂的境地,你可能永远不会离开。