Ответ 1
Появляется (ваша версия). Clang по-прежнему придерживается поведения С++ 11 в этом отношении. В С++ 11 вам пришлось использовать std::move
в этом случае, потому что тип vlist
отличается от типа возвращаемого значения, и поэтому предложение "при возврате lvalue, сначала попробуйте его как rvalue" не применяются.
В С++ 14 это ограничение "одинаковых типов" было отменено, поэтому в С++ 14 вам не нужно использовать std::move
в операторе return. Но если вам нужен код для компиляции с вашей текущей инструментальной цепочкой, просто добавьте его туда:
return std::move(vlist);
Точная формулировка С++ 11 такова:
12.8/32 Когда критерии для исключения операции копирования выполняются или выполняются, за исключением того, что источник object - это параметр функции, а подлежащий копированию объект определяется значением lvalue, разрешением перегрузки до выберите конструктор для копии сначала, как если бы объект был обозначен rvalue....
Необходимо выполнить критерии для копирования (включая "тот же тип" ); они просто немного расширены для покрытия параметров.
В С++ 14 (N4140) формулировка шире:
12.8/32 Когда критерии для исключения операции копирования/перемещения выполняются, но не для объявления исключения, и объект, подлежащий копированию, обозначается lvalue, или когда выражение в выражении
return
является (возможно, в скобках) id-выражение, которое называет объект с автоматическим временем хранения, объявленным в теле или Параметр-объявление-предложение самой внутренней функции включения или лямбда-выражения,. для выбора конструктора для копии сначала выполняется так, как если бы объект был обозначен rvalue.
(Акцент мой)
Как вы можете видеть, для случая return
больше не требуются копии критериев элиции.