Действительно ли необходим std :: move в списке инициализации конструктора для тяжелых элементов, передаваемых по значению?
Недавно я прочитал пример изcppreference ... / вектор / emplace_back:
struct President
{
std::string name;
std::string country;
int year;
President(std::string p_name, std::string p_country, int p_year)
: name(std::move(p_name)), country(std::move(p_country)), year(p_year)
{
std::cout << "I am being constructed.\n";
}
Мой вопрос: этоstd::move
действительно необходимо? Я хочу сказать, что этоp_name
не используется в теле конструктора, так что, может быть, в языке есть какое-то правило использовать семантику перемещения для него по умолчанию?
Было бы очень неудобно добавлять std :: move в списке инициализации для каждого тяжелого члена (например,std::string
, std::vector
). Вообразите сотни проектов KLOC, написанных на C ++ 03 - мы добавим это вездеstd::move
?
Этот вопрос:двигаться-конструктор-и-инициализации-лист ответ говорит:
Как золотое правило, всякий раз, когда вы берете что-то по ссылке rvalue, вам нужно использовать это внутри std :: move, а когда вы берете что-то по универсальной ссылке (то есть выводите шаблонный тип с &&), вам нужно использовать это внутри std :: вперед
Но я не уверен: передача по значению скорее не универсальная ссылка?
[ОБНОВИТЬ]
Чтобы сделать мой вопрос более понятным. Можно ли рассматривать аргументы конструктора как XValue - я имею в виду значения с истекающим сроком?
В этом примере AFAIK мы не используемstd::move
:
std::string getName()
{
std::string local = "Hello SO!";
return local; // std::move(local) is not needed nor probably correct
}
Итак, нужно ли это здесь:
void President::setDefaultName()
{
std::string local = "SO";
name = local; // std::move OR not std::move?
}
Для меня эта локальная переменная является переменной с истекающим сроком действия, поэтому можно применить семантику перемещения ... И это похоже на аргументы, передаваемые по значению ....