Pregunta

Puede alguien me explique por qué hay una diferencia entre estas dos afirmaciones?

class A{};

const A& a = A();         // correct 

A& b = A();               // wrong

Se dice inicialización no válido de referencia no const de tipo A& de un temporal de tipo A

¿Por qué const importa aquí?

¿Fue útil?

Solución

referencias

No-const deben ser inicializadas con L-valores. Si usted podría inicializar con los temporales, a continuación, lo que haría la siguiente?

int& foo = 5;
foo = 6; // ?!

referencias const tiene la propiedad especial que se extienden la vida del árbitro, y puesto que son const, no hay ninguna posibilidad de que se le intenta modificar algo que no se sienta en la memoria. Por ejemplo:

const int& foo = 5;
foo = 6; // not allowed, because foo is const.

Recuerde que las referencias de verdad tiene que referirse a algo, no sólo a las variables temporales. Por ejemplo, la siguiente es válido:

int foo = 5;
int& bar = foo;
bar = 6;
assert(foo == 6);

Otros consejos

La terminología en este es un poco confuso; es posible que desee que investigar un poco más. Aquí está la respuesta corta sin embargo:

Se le asigna un objeto temporal (el resultado de llamar al constructor de la clase) a una variable. Un objeto temporal es un valor R. No se puede asignar un valor R de una referencia no const.

Se le permite asignar un valor R a una referencia constante, aunque la razón de lo que le está bastante oscuro.

En lenguaje C ++ es ilegal para fijar una referencia no constante a un valor de lado derecho, mientras que es perfectamente bien para adjuntar una referencia constante a un valor de lado derecho. Por ejemplo, esto es legal

const int& r = 5;

Si bien esto no es

int &r = 5; // ERROR

Un objeto temporal del tipo A devuelto por el A() expresión es un valor de lado derecho, por lo que la regla anterior se aplica en su caso también.

Para un / rvalue temporal, que sólo puede tener una referencia constante.

Puede tener una referencia no const a un / lvalue no temporal.

A a;
A& b = a;

Creo que la razón por la cual es reforzar el hecho de que un valor de lado derecho es temporal ya que hay poco valor en ser capaz de modificar algo que va a desaparecer momentáneamente.

Debido a que la norma dice así:

  

§8.5.3.5 ... De lo contrario, la referencia será una referencia lvalue a un tipo const no volátil ...

Sin embargo, si quieres mucho, lo puede conseguir:

#include <iostream>
int main()
{
  const int & cr=5;
  int & r=const_cast<int &>(cr);
  r=6;
  std::cout<<r;
}
// outputs 6 with c++/clang++, Debian 8, amd64

Pero tenga en cuenta que la supuesta cr constante no es const más, también, y se incurre en un comportamiento indefinido. (§1.9 (4))

Según lo sugerido por el código anterior, no hay ninguna razón técnica por la diferencia. Por el contrario, los diseñadores tuvieron pesadillas con lo que los usuarios harían con referencias no constante a los temporales.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top