Всегда создается новый std::string
для заполнения аргумента name
до вызова Player(std::string name)
.
Разрешение перегрузки определяет, будет ли вызываться копия ctor или ctor с перемещением std::string
.
Случай 1: Player player1(s);
Новая строка создается копия ctor с подписью basic_string( const basic_string& other );
, потому что 's' было lvalue.
Общая сумма операции, которую вы платите, составляет 1 перемещение и 1 копирование конструкций строки:
- Один экземпляр ctor, для
name
arg к ctor - Один ход ctor, для
m_name
члена класса
Случай 2: Player player2(std::move(s));
Новая строка создается ctor хода для std::string
с подписью basic_string( basic_string&& other ) noexcept;
Во втором случае вы вызываете std::move
, что приводит к преобразованию s
в rvalue-ссылку. std::string
имеет 2 конструктора, один из которых принимает const std::string&
, другой - std::string&&
. Ссылка rvalue может связываться как с ссылкой lvalue, так и с ссылкой rvalue, но версия ссылки rvalue лучше подходит, поэтому она будет выбрана.
Общая сумма операции, которую вы платите, составляет 2 конструкции перемещения строки:
- Один ход ctor, для аргумента
name
в ctor - Один ход ctor, для
m_name
члена класса
Обратите внимание, что, как отмечают @aschepler и @underscore_d, ctor хода std::string
не нуждается в очистке строки источника , Не следует зависеть от этого поведения, так как оно не гарантировано и зависит от того, как реализован ctor перемещения для строк.