C++ 11 - 移动非局部变量安全吗?

C++ 11 - Is moving non local variable safe?

假设我有一个函数如下:

void a_fct( std::vector<double> &some_vector )
{
  std::vector<double> a_temporary_vector = some_vector;

  ... some stuff involving only a_temporary_vector ...

  some_vector = a_temporary_vector;
}

这当然有点傻,但它只是为了提出以下一般性问题:

在这两种情况下,我可以期望它适用于任何 STL 实现吗?

标准(在 17.6.5.15 中)说:

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.

因此,some_vector 在被移动后需要有一个(未指定但)有效的状态。您可以从它临时移动到您,然后再从临时移动到 some_vector.

std::vector<double> a_temporary_vector = std::move(some_vector);
// do stuff only on a_temporary_vector but not some_vector
some_vector = std::move(a_temporary_vector);

指向 some_vector 本身的指针和引用仍然有效,但指向 some_vector 内容的指针或引用则不是(正如您在将对象传递给采用非常量的函数时通常所期望的那样参考)。

注意:在这种情况下,如果您不确定是否要移动,可以使用 swap

void foo( std::vector<double> &some_vector )
{
  // swap contents of some_vector into temporary
  std::vector<double> a_temporary_vector;
  a_temporary_vector.swap(some_vector);

  // operate on temporary

  // swap content back into some_vector
  a_temporary_vector.swap(some_vector);
  some_vector = a_temporary_vector;
}

是的,以上都是绝对安全的。

移入或移出参数向量确实会改变它,但这正是非常量引用参数本来要做的事情。将临时向量移动到输出参数的结果等同于复制方法。

指向参数向量的指针也没有问题。 some_vector 仍将是与以前相同的对象,您只是更改了它的内容。

指针、迭代器和对 some_vector 原始数据的引用当然会失效,无论复制还是移动。