Когда i передается по значению, d становится пустым,
Если быть точным, d
будет в каком-то допустимом состоянии, не указанном в стандарте C ++. Пустой - одна из возможностей.
std::move
сам по себе никогда не вызывает непосредственный вызов конструктора перемещения. Привязка ссылки rvalue к объекту также не вызывает непосредственного вызова конструктора перемещения.
Только инициализация объекта с неконстантным значением r приведет к перемещению аргумента. В этом примере std::string i
инициализируется с неконстантным значением r, и будет вызван конструктор перемещения.
В качестве причины, почему код в текущем состоянии компилируется, если d приведен к x-значение?
Поскольку тип имеет (не удаленный) конструктор перемещения. Следовательно, аргумент может быть инициализирован из значений r.
Я думал, что если бы у нас был std :: string i, была сделана копия ссылки на rvalue.
std::string i
не является ссылкой. Это переменная типа std::string
, и поэтому с ней связан объект типа std::string
. Этот объект инициализируется с выражением, которое передается в функцию в качестве аргумента.
Кроме того, если я увижу, что вывод d по-прежнему такой же, как до применения std :: move, что делает в данном случае это означает?
Если вы вызываете некомментированную версию функции со значением r, то аргумент будет перемещен из. Если значение такое же, как было, то это просто означает, что значение такое же. Вы не можете предполагать, что значение будет таким же или не будет таким же.
Означает ли это, что d все еще занимает место, которое изначально занимало?
Предполагая, что под "пробелом" вы подразумеваете хранилище, в котором находится переменная, тогда, конечно, оно все еще занимает то же хранилище. Адрес объекта никогда не меняется в течение всего времени существования объекта.