auto&& переменные не являются ссылками на rvalue
Почему auto&& не является ссылкой на rvalue?
Widget&& var1 = Widget(); // rvalue reference
auto&& var2 = var1; //var2 not rvalue reference
ниже приведен справочный пример
void f(Widget&& param); // rvalue reference
Widget&& var1 = Widget(); // rvalue reference
Почему var2 не является ссылкой на rvalue, а f и var2 являются ссылками на rvalue?
2 ответа
Как только тип инициализатора определен, компилятор определяет тип, который заменит ключевое слово auto
использование правил вывода аргументов шаблона из вызова функции (подробности см. в разделе Вывод аргументов шаблона # Другие контексты). Ключевое слово auto
может сопровождаться модификаторами, такими как const
или же &
, который будет участвовать в типе удержания.
Например, учитывая
const auto& i = expr;
Тип i
это точно тип аргумента u
в воображаемом
template template<class U>
void f(const U& u)
Если вызов функции f(expr)
был скомпилирован.
В общем, можно подумать как ниже.
template template<class U>
void f(paramtype u)
Следовательно, auto&&
может выводиться либо как ссылка lvalue, либо как ссылка rvalue в соответствии с инициализатором.
В вашем случае мнимый шаблон будет выглядеть так
template template<class U>
void f(U&& var2){}
f(var1)
Вот,var1
называется rvalue, который рассматривается как lvalue, так var2
будет выведено как lvalue .
Рассмотрим следующие примеры:
auto&& var2 = widget() ; //var2 is rvalue reference here .
int x=10;
const int cx=10;
auto&& uref1 = x; // x is int and lvalue, so uref1's type is int&
auto&& uref2 = cx; // cx is const int and lvalue, so uref2's type is const int&
auto&& uref3 = 27; // 27 is int and rvalue, so uref3's type is int&&
auto&&
является декларацией эквивалента пересылки ссылок (с идентичными правилами вычета). Таким образом, он будет выведен на ссылку lvalue, когда инициализатором является lvalue. Тем не мение, var
является lvalue (так как это имя переменной), следовательно, var2
является ссылкой на lvalue.