c++ templates const function-templates const-reference

c++ - ¿Por qué `const T &` no está seguro de ser const?



templates function-templates (2)

Bienvenidos a const y al colapso de referencia . Cuando tienes const T& , la referencia se aplica a T , y también lo hace la const . Llamas g como

g<int&>(n);

por lo que ha especificado que T es un int& . Cuando aplicamos una referencia a una referencia de valor l, las dos referencias se colapsan en una sola, por lo que int& & convierte en int& . Luego llegamos a la regla de [dcl.ref]/1 , que establece que si aplica const a una referencia, se descartará, por lo que int& const simplemente se convierte en int& (tenga en cuenta que en realidad no puede declarar int& const , tiene que provienen de un typedef o plantilla). Eso significa para

g<int&>(n);

en realidad estás llamando

void f(int& a, int& b)

y en realidad no estás modificando una constante.

Habías llamado g como

g<int>(n); // or just g(n);

entonces T sería int , f habría sido eliminado como

void f(int a, const int& b)

Dado que T ya no es una referencia, la const y la aplicación & se aplican a ella, y usted habría recibido un error de compilación al intentar modificar una variable constante.

template<typename T> void f(T a, const T& b) { ++a; // ok ++b; // also ok! } template<typename T> void g(T n) { f<T>(n, n); } int main() { int n{}; g<int&>(n); }

Tenga en cuenta: b es de const T& and ++b está bien!

¿Por qué es const T& no estoy seguro de ser const?


Sé que ya hay una respuesta aceptada que es correcta, pero solo para agregarle un poco, incluso fuera del ámbito de las plantillas y solo en las declaraciones de funciones en general ...

( const T& )

no es lo mismo que

( const T )

En su ejemplo que coincide con el primero, tiene una referencia constante. Si realmente desea un valor constante que no sea modificable, elimine la referencia como en el segundo ejemplo.