лязг здесь правильный.Filed 87530 .
Правило для операторов возврата: [class.copy.elision] / 3 :
В следующем экземпляре-при инициализации, операция перемещения может использоваться вместо операции копирования:
- Если выражение в операторе
return
([stmt.return]) является (возможно, заключено в скобки) id-выражение , которое именует объект с автоматической продолжительностью хранения, объявленным в теле, или параметр-объявление-условие самой внутренней функции, или лямбда-выражение , или - , если операндом throw-выражения является имя энергонезависимого автоматического объекта (кроме функции или параметра catch-clause ), область действия которого не выходит за пределыконец самого внутреннего охватывающего блока try (если он есть), разрешение перегрузки
для выбора конструктора для копии сначала выполняется так, как если бы объект был обозначен значением r.Если первое разрешение перегрузки не удалось или не было выполнено, или если тип первого параметра выбранного конструктора не является rvalue-ссылкой на тип объекта (возможно, cv-qualified) , разрешение перегрузки выполняется снова, рассматривая объект как lvalue.[Примечание: это двухэтапное разрешение перегрузки должно выполняться независимо от того, будет ли выполнено копирование.Он определяет конструктор, который будет вызван, если elision не выполняется, и выбранный конструктор должен быть доступен, даже если вызов исключен.- конец примечания]
Акцент на шахте.
Мы встречаемся с первым маркером, возвращаем id-выражение , которое называет энергонезависимый автоматический объект,Таким образом, мы выполняем разрешение перегрузки, как если бы это было значение.Это разрешение перегрузки успешно, есть конструктор, который принимает Base&&
.Однако обратите внимание на жирную часть.Тип этого параметра: , а не - ссылка на тип объекта.
Следовательно, мы снова попытаемся рассмотреть объект как lvalue.Это разрешение перегрузки не удается.
В результате программа некорректно сформирована.