移动物体怎么办?

时间:2011-08-11 14:19:13

标签: c++ c++11 variable-assignment swap move-semantics

标准是否准确定义了移动对象后我可以对其执行的操作?我曾经认为你用移动物体做的所有事情都会破坏它,但这还不够。

例如,使用标准库中定义的函数模板swap

template <typename T>
void swap(T& a, T& b)
{
    T c = std::move(a); // line 1
    a = std::move(b);   // line 2: assignment to moved-from object!
    b = std::move(c);   // line 3: assignment to moved-from object!
}

显然,必须可以分配给移动的对象,否则第2行和第3行会失败。那么移动对象我还能做些什么呢?我在哪里可以找到标准中的这些细节?

(顺便说一下,为什么第1行中T c = std::move(a);代替T c(std::move(a));?)

2 个答案:

答案 0 :(得分:104)

17.6.5.15 [lib.types.movedfrom]

  

可以移动C ++标准库中定义的类型的对象   (12.8)。可以明确指定或隐式指定移动操作   产生。除非另有规定,否则此类移动物体应   被置于有效但未指明的状态。

当对象处于未指定状态时,您可以对没有前提条件的对象执行任何操作。如果存在您希望执行前提条件的操作,则无法直接执行该操作,因为您不知道对象的未指定状态是否满足前提条件。

通常没有先决条件的操作示例:

  • 破坏
  • 分配
  • const观察员,例如getemptysize

通常确实具有先决条件的操作示例:

  • 解引用
  • pop_back

此答案现在以视频格式显示在此处:http://www.youtube.com/watch?v=vLinb2fgkHk&t=47m10s

答案 1 :(得分:50)

Moved-from对象存在于未指定但有效的状态。这表明虽然对象可能不再能够做很多事情,但它的所有成员函数仍然应该表现出定义的行为 - 包括operator= - 以及所有成员处于已定义的状态 - 并且它仍然需要销毁。标准没有给出具体的定义,因为它对每个UDT都是唯一的,但您可能能够找到标准类型的规范。有些像容器是相对明显的 - 它们只是移动它们的内容而空容器是一个明确定义的有效状态。基元不会修改移动的对象。

旁注:我相信它是T c = std::move(a)所以如果移动构造函数(或复制构造函数,如果没有提供移动)是显式的,那么函数将会失败。