1

A を値で受け取る最初の例は 2 つの移動を行い、refref によるものは 1 つの移動のみを行います。違いはなんですか?

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::moveますstd::forward

于 2012-11-21T16:03:40.280 に答える