Ответ 1
Update:
Явный переход не требуется в современных версиях компилятора.
Core DR 1579 изменил правила, так что возвращаемое значение будет рассматриваться как rvalue, даже если типы не совпадают. GCC 5 реализует новое правило для С++ 11, а также С++ 14.
Оригинальный ответ:
Это не ограничение unique_ptr
, это ограничение языка, то же ограничение распространяется на любой оператор return
, который вызывает конструктор преобразования, который принимает ссылку rvalue:
struct U { };
struct T {
T(U&&) { }
};
T f() {
U u;
return u; // error, cannot bind lvalue to U&&
}
Это не будет компилироваться, потому что [class.copy]/32 говорит:
Когда критерии для выполнения операции копирования выполняются или выполняются, за исключением того факта, что исходный объект является параметром функции, а подлежащий копированию объект определяется значением lvalue, разрешением перегрузки, чтобы выбрать конструктор для копия сначала выполняется так, как если бы объект был обозначен rvalue.
Это означает, что выражение в выражении return
может рассматриваться только как rvalue, если оно имеет право на копирование/перемещение elision (aka NRVO), но это слишком ограничительно, потому что это означает, что оно применяется только тогда, когда тип точно то же самое, несмотря на то, что переменная всегда выходит за пределы области видимости, поэтому было бы разумно всегда относиться к ней как к rvalue (технически как значение x, истекающее значение.)
В последнее время предложил Ричард Смит (и ранее Xeo) и я думаю, что это очень хорошая идея.