2012-05-29 6 views
9

me encontré con un fragmento de códigoconst reference se le puede asignar un int?

const int& reference_to_const_int = 20; 
cout<<"\n reference_to_const_int = "<<reference_to_const_int<<endl;  

Este código se compila & ejecutable en el entorno de salida: -

reference_to_const_int = 20 

Esto es algo extraño en mi lugar. Como sé que la referencia no ocupa memoria & son alias a otras variables. por lo tanto, no podemos decir

int& reference_to_int = 30; 

La declaración anterior no compilará que da un error: -

error: invalid initialization of non-const reference of type ‘int&’ from an rvalue of type ‘int’ 

Lo que está ocurriendo exactamente en el caso "const int &"? Se desea una explicación completa.

Amablemente ayuda.

Gracias

+2

leyeron: http://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/ –

+0

dándole un poco más de pensamiento, parece que * tendría * que ser legal. Si no fuera así, nunca serías capaz de establecerlo sin crear más variables. –

+0

@GigaWatt: ¿De qué está hablando? Créanme, si "es" * debería * ser legal, sería * sería *. :) –

Respuesta

11

Un temporal se crea, y es legal para vincular una referencia const a ella, pero es ilegal para obligar a éste a un no const uno.

Es como:

const int& reference_to_const_int = int(20); //LEGAL 
     int& reference_to_const_int = int(20); //ILLEGAL 

Una referencia const extiende la vida de un temporal, es por eso que esto funciona. Es solo una regla del lenguaje.

+0

temporal no sale temporalmente del alcance después de la declaración de asignación, por lo que la instrucción de impresión hace referencia a un 'int' que se ha salido del alcance? –

+3

@FlorianSowade no, las referencias de const extienden la vida de un temporal. –

+4

Pero tenga cuidado, las referencias de const no extienden la duración en TODOS los casos. Y también tenga en cuenta que los compiladores de Microsoft C++ rompen las reglas y permiten referencias vinculantes que no sean '' a los temporales. –

5

Este comportamiento es más fácil de entender cuando vemos lo que sucede cuando vinculamos una referencia a un objeto temporal. Si escribimos

const int& reference_to_const_int = 20; //A temporay object int(20) is created. 

el compilador transforma el código anterior en algo como esto:

int temp = 20; 
const int& reference_to_const_int = temp; 

Si no se reference_to_const_int const, entonces podríamos asignar un nuevo valor a reference_to_const_int. Hacerlo no cambiaría el literal 20, sino que cambiaría la temperatura, que es un objeto temporal y, por lo tanto, inaccesible. Permitir que solo las referencias const se vinculen a valores que requieren temporarios evita el problema completamente porque una referencia constante es de solo lectura.

¿Por qué C++ permite que las referencias const acepten objetos temporales o RVALUES (como literales)?

Los lugares más comunes que vemos las referencias son como argumentos de funciones o valores devueltos. Cuando se utiliza una referencia como argumento de función, cualquier modificación de la referencia dentro de la función provocará cambios en el argumento fuera de la función.

Si la función puede esperar/aceptar objetos temporales o literales como entradas y si la función respeta la consistencia del objeto, convirtiendo el argumento en una referencia constante permitirá que la función se use en todas las situaciones.

Los objetos temporales siempre son const, por lo que si no utiliza una referencia constante, ese argumento no será aceptado por el compilador.

void f(int&) {} 
void g(const int&) {} 
int main() 
{ 
    //f(1); //Error 
    g(1); //OK 
} 
Cuestiones relacionadas