семантика возвращаемого типа ссылки r-value?
представляет ли такой возвращаемый тип что-то значимое в c++11?
template <typename R>
R&& grabStuff();
T instance = grabStuff<T>();
Я надеюсь, что grabStuff
должен выдать ошибку времени компиляции, если R
не имеет конструктора перемещения, так как это, похоже, запрещает возвращаемому типу использовать конструктор копирования
3 ответов
Как всегда, при возврате ссылок вы должны вернуть ссылку на то, что все еще живо после возвращения функции. Как вы это сделаете, зависит от вас. Пример:
T global_thing;
T && get() { return std::move(global_thing); }
struct Foo { Foo(T &&); /* ... */ };
int main()
{
global_thing.reset();
Foo a(get());
global_thing.reset();
Foo b(get());
}
более типичным примером возврата ссылки rvalue является std::move
сам, однако, который возвращает ссылку на вещь, которую вы передаете на it (и, таким образом, это ответственность вызывающего абонента за предоставление действительного ввода).
это может быть значимым в зависимости от того, что вы хотите с ним сделать, и как вы реализовали функцию.
В самом деле std::move
тип возврата T&&
(ссылка rvalue), которая имеет смысл, поскольку она определяет саму цель существования std::move
в библиотеке C++11:
Если возвращаемый тип функции является ссылкой rvalue, то результатом вызова функции является xvalue; если возвращаемый тип не является ссылкой, то результатом вызова функции является prvalue.
и xvalue и prvalue являются rvalues, между ними есть некоторые незначительные различия, больше похожие на различия между ссылкой и не ссылкой. Например, xvalue может иметь неполный тип, в то время как prvalue обычно имеет полный тип или тип void. Когда ИД типа применяется к xvalue, тип которого является полиморфным типом класса, результат относится к динамическому типу; а для prvalue результат относится к статическому типу.
для вашего заявления объявления T instance = grabStuff<T>();
, Если T-тип класса, я думаю, что в этом контексте нет разницы между xvalue и prvalue.
инициализатор является rvalue, поэтому компилятор предпочитает конструктор перемещения. Но если конструктор перемещения не объявлен, а конструктор копирования с параметром ссылки const объявляется, то этот конструктор копирования будет выбран, и ошибки нет. Я не знаю, почему ты хочешь, чтобы это было ошибкой. Если это ошибка, любой старый код будет неправильным при копировании-инициализации некоторого объекта из rvalue.