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

时间:2015-04-25 14:56:51

标签: c++ c++11 stl move

说我有一个类似的功能:

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;
}

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

  • 在我看来,应该将a_temporary_vector移到some_vector这里,因为它超出了范围。但将some_vector移入a_temporary_vector而不是复制是否安全?

  • 现在想象一下,代码中的其他地方,我有一个指向这里作为参数给出的向量的指针。如果我将some_vector移到a_temporary_vector,此指针是否仍然指向它?

在这两种情况下,我可以期望它对任何STL实现都是正确的吗?

2 个答案:

答案 0 :(得分:3)

是的,以上所有内容都非常安全。

移入或移出参数向量会改变它,但这是非const引用参数的意思。将临时矢量移动到输出参数的结果等同于复制方法。

指向参数向量的指针也没问题。 some_vector仍然是与以前相同的对象,您只需更改其内容即可。

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

答案 1 :(得分:2)

标准(17.6.5.15)说:

  

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

因此,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;
}