Вы должны предпочесть передачу по значению, если вы собираетесь сделать копию с неподвижными значениями.Например, ваша const&
версия WriteDefaultFileOutput
явно копирует параметр, а затем перемещает копию с версией перемещения.Это означает, что если WriteDefaultFileOutput
вызывается с подвижным значением (xvalue или prvalue), то оно будет перемещено, а если оно вызывается с lvalue, оно будет скопировано.
Это означает, что Нет Разница между двумя формами этой функции.Подумайте об этом:
WriteDefaultFileOutput(L"SomeString");
В вашем первом случае будет создан временный wstring
.Временные значения являются значениями, поэтому они будут «перемещены» в параметр (поскольку wstring
имеет конструктор перемещения).Конечно, любой компилятор, достойный его соли, исключит этот шаг и просто создаст временное значение непосредственно в параметре.
Во втором случае более или менее происходит то же самое.Временный wstring
создан.Временные значения являются значениями, поэтому они могут связываться с &&
типами параметров.Поэтому он вызовет первую версию вашей функции со ссылкой на временное значение r.Единственное возможное отличие будет от компилятора, который не исключит ход.И даже тогда, перемещение не так дорого (в зависимости от вашей basic_string
реализации).
Теперь рассмотрим это:
std::wstring myStr{L"SomeString"};
WriteDefaultFileOutput(myStr);
В первом случае вызов WriteDefaultFileOutput
приведет к копированию значения myStr
в параметр функции.
Во втором случае myStr
является lvalue. не может привязаться к параметру &&
.Поэтому единственная версия, которую он может вызвать, - это версия const&
.Эта функция создаст копию вручную, а затем переместит копию вместе с другой.
Аналогичный эффект.Ваша первая версия имеет меньше кода, так что следуйте по понятным причинам.
В общем, я бы сказал, что есть только две причины для принятия параметра в качестве &&
:
- Вы пишете конструктор перемещения.
- Вы пишете функцию пересылки и вам необходимо использовать идеальную пересылку.
Во всех других случаях, когда вы хотите, чтобы перемещение было возможным, простопринять значение.Если пользователь хочет скопировать, пусть копирует.Я полагаю, если вы хотите явно запретить копирование параметра, вы можете взять &&
.Но главная проблема заключается в ясности.
Если вы берете параметр-значение, а пользователь предоставляет перемещаемое значение, то предоставленное пользователем значение будет всегда перемещаться.Например, ваша &&
версия WriteDefaultFileOutput
не имеет для фактического перемещения данных из своего параметра.Это конечно может.Но это не обязательно.Если бы он принял значение, то он бы уже запросил данные.
Поэтому, если функция принимает параметр значения, и вы видите std::move
в этом значении, то вы знаете объект, который был перемещен, теперь пуст. гарантировано было перемещено из.