在此示例中,移动和前进之间存在差异

时间:2012-11-21 15:53:13

标签: c++ c++11 move-semantics perfect-forwarding

采用A by值的第一个示例执行两次移动,而refref执行的只移动一次。有什么区别?

struct A
{
  A() { cout << "constructor" << endl;}
  A(const A&) { cout << "copy constructor " << endl;}
  void operator=(const A&) { cout << "assignment operator" << endl; }
  A( A&&) { cout << "move copy constructor" << endl;}
  void operator=(A&&) { cout << "move assignment operator" << endl;}
};
struct C {
  void func(A t) {
    d.a = std::move(t);
  }
  struct Data {
    A a;      
  };
  Data d;
};
struct B {
  void func(A t) {
    C c;
    c.func(std::move(t));
  }
};
//////////////////////////////////////////////////////////
struct C {
  template<class T>
  void func(T&& t) {
    d.a = std::forward<T>(t);
  }
  struct Data {
    A a;      
  };
  Data d;
};
struct B {
  template<class T>
  void func(T&& t) {
    C c;
    c.func(std::forward<T>(t));
  }
};

1 个答案:

答案 0 :(得分:2)

来自cppreference.com

  

在功能模板中根据以下配方使用时,   将参数转发给另一个函数,与传递给它完全一样   调用函数。

template<typename T> 
wrapper(T&& arg) {
   foo(std::forward<T>(arg)); 
}

所以在您的代码段中

struct B {
  template<class T>
  void func(T&& t) {
    C c;
    c.func(std::forward<T>(t));
  }
};

std::foward<T>(t)只会将T&&对象转发给c.func(),与B::func()完全相同。这不需要移动,这就是使用std::forward<T>看到更少移动的原因。

我真的建议查看Scott Meyer关于std::movestd::forward {{1}}的主题的博文:http://scottmeyers.blogspot.com/2012/11/on-superfluousness-of-stdmove.html