Теперь я возвращаю этот класс через lvalue следующим образом:
MyClass func()
{
return MyClass();
}
Нет, возвращаемое выражение - xvalue (разновидность rvalue), используемое для инициализации результата для возврата по значению (все немного сложнее, начиная с C ++ 17, но это все еще суть этого, кроме того, вы находитесь на C ++ 11).
В этом случае конструктор перемещения вызывается при возврате объекта класса, и все работает как положено.
Действительно, rvalue инициализирует ссылку rvalue, и, таким образом, все это может соответствовать конструкторам перемещения.
Когда я изменяю код выше:
& hellip; теперь выражение MyClass() << 5
имеет тип MyClass&
. Это никогда не будет ценным. Это lvalue. Это выражение ссылается на существующий объект.
Итак, без явного std::move
, это будет использоваться для copy-initialise результата. И, поскольку ваш конструктор копирования удален, это не может работать.
Я удивлен, что пример компилируется вообще, поскольку временная переменная не может использоваться для инициализации ссылки на lvalue (первый аргумент вашего оператора), хотя известно, что некоторые цепочки инструментов (MSVS) принимают это как расширение.
тогда вернется std::move(MyClass() << 5);
работа?
Да, я верю в это.
Однако на это очень странно смотреть, и он заставляет читателя перепроверить, чтобы не было оборванных ссылок. Это говорит о том, что есть лучший способ сделать это, что приведет к более ясному коду:
MyClass func()
{
MyClass m;
m << 5;
return m;
}
Теперь вы все еще получаете ход (потому что это специальное правило при return
использовании локальных переменных ) без каких-либо странных выходок. И, в качестве бонуса, <<
звонок полностью соответствует стандартам.