Недавно я прочитал пример из cppreference.../vector/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, написанных на С++ 03, - добавим ли мы везде этот std::move
?
Этот вопрос: move-constructor-and-initialization-list отвечает:
Как золотое правило, всякий раз, когда вы принимаете что-то по ссылке rvalue, вы нужно использовать его внутри std:: move, и всякий раз, когда вы принимаете что-либо универсальной ссылки (т.е. выведенного шаблонного типа с & &), вам необходимо используйте его внутри std:: forward
Но я не уверен: передача по значению скорее не универсальная ссылка?
[ОБНОВЛЕНИЕ]
Сделать мой вопрос более ясным. Могут ли аргументы конструктора рассматриваться как 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?
}
Для меня эта локальная переменная - переменная expying - поэтому можно применить семантику переноса... И это похоже на аргументы, переданные значением....