c++ templates c++11 c++14 forwarding-reference

c++ - ¿Por qué agregar `const` hace la referencia universal como rvalue?



templates c++11 (1)

El nombre oficial no es referencia universal, sino referencia de reenvío . El Standard establece que solo las referencias de valor a los parámetros de la plantilla no calificados de cv se incluyen en esta categoría:

14.8.2.1 Deducir argumentos de plantilla de una llamada de función [temp.deduct.call]

3 Si P es un tipo calificado por el CV, los calificadores del CV de nivel superior del tipo P se ignoran para la deducción del tipo. Si P es un tipo de referencia, el tipo referido por P se usa para la deducción de tipo. Una referencia de reenvío es una referencia rvalue a un parámetro de plantilla no calificada cv. Si P es una referencia de reenvío y el argumento es un valor l, se usa el tipo "referencia a valor l" a en lugar de A para la deducción de tipo. [Ejemplo:

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

- ejemplo final]

Permitir que const T&& comporte como reenvío de referencias, haría imposible sobrecargar una función de plantilla que toma solo una referencia de rvalor como parámetro.

Actualización : como @HowardHinnant menciona en los comentarios, const T&& tiene sus usos (consulte también estas preguntas y respuestas ).

He estado leyendo acerca de las referencias universales en la última obra maestra de Scott sobre c ++ 11 y 14, dicho esto a pesar de un argumento asignado a lvalue o a un parámetro de referencia de tipo rvalue, hay algo en medio llamado referencia universal que se puede deducir de o bien l / rvalue basado en el rasgo de tipo de un argumento que se aprobó. Pude entender lo que hace que el parámetro sea una referencia universal, pero lo que no me queda claro es por qué agregar const al tipo de parámetro const T&& p hace que p sea rvalue:

template<typename T> void f(T&& param); // param is an universal reference template<typename T> void f(const T&& param); // param is an rvalue reference

¿El const hace más que esto cuando se asigna al parámetro de referencia?