Использование std::move() при инициализации членов в конструкторе

Допустим, имеем типичный класс:

class worker
{
  std::string name;
  std::string lastname;
  std::string dob;
public:
  worker(std::string &&n, std::string &&l, std::string &&d)
    : name(n), lastname(l), dob(d)
  {  }
  ~worker() = default;
};

Какой вариант конструктора лучше использовать, такой, или с std::move()?

worker(std::string &&n, std::string &&l, std::string &&d)
        : name(std::move(n)),
          lastname(std::move(l)),
          dob(std::move(d))
{  }

Ответы (2 шт):

Автор решения: Harry

Вот живой пример -

#include <iostream>
#include <iomanip>

using namespace std;

class Test {
public:
    Test()             { cout << "Test()\n"; }
    Test(int x):val_(x){ cout << "Test(" << x << ")\n"; }
    Test(const Test& t):val_(t.val_) { cout << "Test(const Test& " << t.val_ << ")\n"; }
    Test(Test&&t)      :val_(t.val_) { cout << "Test(const Test&& " << t.val_ << ")\n"; t.val_ = 0; }
    ~Test()           { cout << "~Test(" << val_ <<")\n"; }
private:
    int val_ = 0;
};

struct Quest
{
    Test t;
    Quest(Test&& t):t(t){}
};

struct Qwest
{
    Test t;
    Qwest(Test&& t):t(move(t)){}
};

int main(int argc, const char * argv[])
{
    Test t(5), s(6);
    Quest q(move(t));
    Qwest w(move(s));
}

Убедились в необходимости move?

→ Ссылка
Автор решения: HolyBlackCat

Ни тот ни другой. В оба конструктора нельзя передавать lvalue.

Например, если у вас есть std::string name = "Bob";, то при вызове конструктора вам придется писать std::move(name) - очень неудобно!

Вот такой конструктор больше подходит:

worker(std::string n, std::string l, std::string d)
        : name(std::move(n)),
          lastname(std::move(l)),
          dob(std::move(d))

А если параметров мало (1-2), то в качестве оптимизации можно сделать 2n конструкторов с параметрами const std::string & и std::string && (во втором случае нужен std::move, как написано в соседнем ответе). Тогда для каждой переменной у вас будет на одно перемещение меньше.

→ Ссылка