Ответ 1
Обзор
Известно, что с С++ 11 параметр типа T&&
называется ссылкой rvalue [ИСО/МЭК 14882: 2011 §8.3.2/p2 Ссылки [dcl.ref]]. То есть, если T
- это тип параметра шаблона или auto
или typedef
для некоторого ссылочного типа lvalue.
примеры:
template<typename T> void foo(T&& p) { // -> T is a template parameter ... } auto &&p = expression;
Хотя технически T&&
в приведенных выше примерах все еще является ссылкой rvalue, его поведение существенно отличается от обычного.
Естественно, вы спросите "почему этот специальный случай не имеет специального синтаксиса". Ответ заключается в том, что синтаксис &&
был преднамеренно перегружен для этой специальной конструкции комитетом С++. Однако они пропустили назвать этот особый случай.
В отсутствие отдельного имени для этой конкретной конструкции Scott Meyers придумал широко известный термин/имя универсальные ссылки.
Однако комитет решил, что это имя не подходит по ряду причин. Таким образом, предложение N4164, сделанное Herb Sutter, Bjarne Stroustrup и Габриэль Дос Рейс предложил изменить название на Ссылки на переадресацию.
Название Ссылки на пересылку оказало наибольшую поддержку в неофициальных обсуждениях среди членов комитета, включая авторов упомянутого выше предложения. Интересно, что именно сам Скотт Мейерс ввел этот термин в своем оригинальном разговоре "Универсальные ссылки". Однако позже он решил согласиться с названием универсальных ссылок. Для этого решения сыграла роль тот факт, что в то время он не думал, что термин пересылки ссылок включает также случай auto&&
.
Почему не универсальные ссылки?
Согласно предложению, термин Универсальные ссылки, хотя и является разумным именем с очевидным значением, в некоторых аспектах он ошибочен.
Универсальная ссылка должна означать следующее:
- Ссылка, которая может использоваться повсюду; или
- Ссылка, которая может использоваться для всего; или
- нечто подобное.
Очевидно, что это не так и не подходит для этой конструкции. Кроме того, это имя побудило бы многих людей считать, что что-то, имеющее такое имя, предназначено для использования "повсеместно". Что-то, что комитет сочтет это плохим.
Кроме того, "универсальные ссылки" действительно даже как таковой, а скорее набор правил для использования ссылок определенным образом в определенном контексте с некоторой поддержкой языка для этого использования, а , который использует переадресацию.
Почему auto&&
также рассматривается случай пересылки
auto&&
также рассматривается как форвардный случай, так как он следует за правилами свертывания ссылок. Например, в:
- Общие лямбда формы,
[](auto&& x){ … }
-
for
- закодированный цикл формы,for(auto &&i : v) { ... }
- Наконец, в общем случае верно, что локальные переменные
auto&&
предназначены для пересылки.
Стандартные словари для ссылок на переадресацию
Термин ссылки пересылки упоминается в
template <class T> int f(T&& heisenreference);
template <class T> int g(const T&&);
int i;
int n1 = f(i); // calls f<int&>(int&)
int n2 = f(0); // calls f<int>(int&&)
int n3 = g(i); // error: would call g<int>(const int&&), which
// would bind an rvalue reference to an lvalue
§14.8.2.5/p10 Вывод аргументов шаблона из типа [temp.deduct.type]:
template <class T> void f(T&&); template <> void f(int&) { } // #1 template <> void f(int&&) { } // #2 void g(int i) { f(i); // calls f<int&>(int&), i.e., #1 f(0); // calls f<int>(int&&), i.e., #2 }