Использование 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, как написано в соседнем ответе). Тогда для каждой переменной у вас будет на одно перемещение меньше.