C ++我是否总是必须使用std :: move来调用移动构造函数?

时间:2016-03-06 18:05:02

标签: c++11 move-semantics

"理论"如果你愿意的话。

为了在类中执行/使用移动构造函数,我是否总是必须使用std::move(...)来告诉编译器我希望移动'一个对象而不是复制它?

在没有使用std::move的情况下,编译器是否会为我调用移动构造函数? (我的猜测是函数返回值?)

3 个答案:

答案 0 :(得分:3)

根据cppreference.com(http://en.cppreference.com/w/cpp/language/move_constructor):

  

只要从相同类型的xvalue初始化对象,就会调用移动构造函数,其中包括

     
      
  • 初始化,T a = std :: move(b);或者T a(std :: move(b));,其中b是T的类型;
  •   
  • 函数参数传递:f(std :: move(a));,其中a是T类型,f是void f(T t);
  •   
  • 功能返回:返回a;在诸如T f()之类的函数内部,其中a是T类型,它具有移动构造函数。
  •   

在大多数情况下,需要std::move

答案 1 :(得分:2)

在以下情况下,编译器将调用不带std::move的移动构造函数:

  • 按值返回本地变量
  • 从相同类型的右值构造对象时

在所有其他情况下,请使用std::move。 E.g:

struct S {
  std::string name;
  S(std::string name) : name(std::move(name)) {}
};

std::unique_ptr<Base> func() {
  auto p = std::make_unique<Derived>();
  return std::move(p); // doesn't work without std::move
}

答案 2 :(得分:1)

std::move只是演员。

unique_ptr<int> global;

auto v = unique_ptr<int>(global); // global is a lvalue, therefore the
unique_ptr(unique_ptr<T>&v) constructor that accepts lvalue references is called.

auto v = unique_ptr<int>(std::move(global)); // move returns a &&rvalue reference, therefore the
unique_ptr(unique_ptr<T>&&v) constructor that accepts &&rvalue references is used.
  

当满足复制操作的省略标准并且要通过左值指定要复制的对象时,首先执行的重载决策以选择复制的构造函数,就好像该对象由 右值指定。

因此,

unique_ptr<int> hello()
{
    unique_ptr<int> local;
    return local;

    // local is an lvalue, but since the critera for elision is met,
    // the returned object is created using local as if it was an rvalue
}

此外,

unique_ptr<int> hello = std::unique_ptr<int>();
// we have a pure rvalue in the right, therefore no std::move() cast is needed.