Отличается между движением и вперед в этом примере

Первый пример, который принимает 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));
  }
};

1 ответ

Решение

С 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>,

Я действительно рекомендовал бы проверить сообщение в блоге Скотта Мейера на эту тему std::move а также std::forward: http://scottmeyers.blogspot.com/2012/11/on-superfluousness-of-stdmove.html

Другие вопросы по тегам