Ответ 1
Обратите внимание на разницу между двумя классами. Для TestNonMovable
(случай 2) вы явно объявите конструктор перемещения как delete
. С помощью TestNonMovable tnm2 = std::move(tnm);
конструктор удаленных перемещений выбирается в разрешении перегрузки, а затем вызывает ошибку.
Для SomeClass
(случай 1) вы явно не объявляете конструктор перемещения и копирования. Конструктор копирования будет неявно объявлен и определен, но конструктор перемещения будет неявно объявлен и определен как удаленный, поскольку он имеет недвижущийся элемент данных. Обратите внимание, что удаленный неявно объявленный конструктор перемещения не будет участвовать в разрешении перегрузки. С помощью SomeClass sc2 = std::move(sc1);
выбирается конструктор копирования, а затем код работает нормально. Ссылка rvalue, возвращаемая из std::move
, может быть привязана к lvalue-reference для const (т.е. const SomeClass&
).
Удаленный неявно объявленный механизм перемещения игнорируется разрешением перегрузки (в противном случае это предотвратит инициализацию копирования от rvalue). (поскольку С++ 14)
BTW: std:: move сам разрешен в обоих случаях. Он не выполняет операцию перемещения, он просто преобразует аргумент в значение rvalue. Операция перемещения происходит при построении в обоих случаях.