auto a = A(3);
означает, что A a = A(3);
так как тип правой стороны A
.
Это означает именно то, что он выглядит следующим образом: A(3)
создает временный A
инициализированную 3
, а затем A a = _____
означает: создать A
называется a
с _____
как инициализаторе.
Таким образом, вы создаете временное, передаете это значение a
в качестве инициализатора, а затем временное уничтожается. Этот тип инициализации (с =
) называется копия-инициализация (хотя не путайте это с «копией», это всего лишь слово).
Конструктор выбирается для построения a
, который принимает A
. Это должен быть либо экземпляр, либо конструктор перемещения. A
имеет конструктор перемещения и конструктор копирования. Последний неявно генерируется и определяется как удаленный, так как существует объявленный пользователем конструктор перемещения.
Определенный как удаленный, не влияет на разрешение перегрузки; и в этом случае конструктор move предпочтительнее конструктора копирования.
Таким образом, ваш код пытается вызвать функцию delete
d, которая является плохо сформированной, следовательно, является ошибкой.
Обратите внимание, что если конструктор перемещения не был удален, то применяется копия elision. Он запускается в некоторых случаях, когда переменная инициализируется из временной или локальная переменная возвращается значением. Правило состоит в том, что компилятор может использовать одну и ту же память как для a
, так и для временного объекта и опустить вызов конструктору copy/move.
Большинство/все составители действительно сделают это в этом случае. Поэтому вы можете написать auto a = A(3);
и на практике не получить лишних ходов. Если вы напишете какой-то код для вашего конструктора move, который выводит что-то, вы, надеюсь, обнаружите, что ничего не выводится.
Если вы хотите абсолютно убедиться в отсутствии ненужной копии или создать объект, который не имеет пригодной для использования копии, и не перемещать конструктор - прекратите писать код, который указывает ненужные копии! A a(3);
достаточный.
Что касается вашего первого комментария, у меня сложилось впечатление, что это часто вводится как «все те же, за исключением технических проблем, которые обычно не возникают». Но, возможно, я помещаю слова в рот. – Hurkyl
Тот, кто вводит их как таковые, должен быть уволен за некомпетентность. – Blindy
Почему компилятор генерирует другой код, когда намерение явно одно и то же? Есть ли случай, когда программист захочет этого поведения? – Shmoopy