1

第一个按值取 A 的例子做了两步,而通过 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));
  }
};
4

1 回答 1

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::forwardhttp: //scottmeyers.blogspot.com/2012/11/on-superfluousness-of-stdmove.html

于 2012-11-21T16:03:40.280 回答