¿Está bien el siguiente (ejemplo artificial) o es un comportamiento indefinido:
// undefined behavior?
const auto& c = SomeClass{};
// use c in code later
const auto& v = c.GetSomeVariable();
fuente
¿Está bien el siguiente (ejemplo artificial) o es un comportamiento indefinido:
// undefined behavior?
const auto& c = SomeClass{};
// use c in code later
const auto& v = c.GetSomeVariable();
Es seguro. Const ref prolonga la vida de temporal. El alcance será el alcance de const ref.
La vida útil de un objeto temporal puede extenderse uniéndose a una referencia de valor constante o a una referencia de valor (desde C ++ 11), consulte la inicialización de referencia para obtener más detalles.
Cada vez que una referencia está vinculada a un objeto temporal o subobjeto del mismo, la vida útil del temporal se extiende para que coincida con la vida útil de la referencia, con las siguientes excepciones :
- un enlace temporal a un valor de retorno de una función en una declaración de retorno no se extiende: se destruye inmediatamente al final de la expresión de retorno. Dicha función siempre devuelve una referencia colgante.
- un enlace temporal a un miembro de referencia en una lista de inicializador de constructor persiste solo hasta que el constructor sale, no mientras exista el objeto. (nota: dicha inicialización está mal formada a partir del DR 1696).
- existe un enlace temporal a un parámetro de referencia en una llamada de función hasta el final de la expresión completa que contiene esa llamada de función: si la función devuelve una referencia, que sobrevive a la expresión completa, se convierte en una referencia colgante.
- existe un enlace temporal a una referencia en el inicializador utilizado en una nueva expresión hasta el final de la expresión completa que contiene esa nueva expresión, no tanto como el objeto inicializado. Si el objeto inicializado sobrevive a la expresión completa, su miembro de referencia se convierte en una referencia colgante.
- existe un enlace temporal a una referencia en un elemento de referencia de un agregado inicializado utilizando la sintaxis de inicialización directa (paréntesis) en oposición a la sintaxis de inicialización de lista (llaves) hasta el final de la expresión completa que contiene el inicializador.
struct A { int&& r; }; A a1{7}; // OK, lifetime is extended A a2(7); // well-formed, but dangling reference
En general, la vida útil de un temporal no puede extenderse aún más "pasándola": una segunda referencia, inicializada a partir de la referencia a la que estaba vinculado el temporal, no afecta su vida útil.
como señaló @Konrad Rudolph (y vea el último párrafo de arriba):
"Si
c.GetSomeVariable()
devuelve una referencia a un objeto local o una referencia de que está extendiendo la vida útil de algún objeto, la extensión de la vida útil no se activa"
c.GetSomeVariable()
devuelve una referencia a un objeto local o una referencia de que está extendiendo la vida útil de algún objeto, la extensión de la vida útil no se activa.No debería haber ningún problema aquí, gracias a la extensión de por vida . El objeto recién construido sobrevivirá hasta que la referencia salga del alcance.
fuente
Sí, esto es perfectamente seguro: el enlace a una
const
referencia extiende la vida útil de lo temporal al alcance de esa referencia.Sin embargo, tenga en cuenta que el comportamiento no es transitivo . Por ejemplo, con
cc
cuelgafuente
Esto es seguro
fuente
Es seguro en este caso específico. Sin embargo, tenga en cuenta que no todos los temporales son seguros de capturar por referencia constante ... por ejemplo
La referencia obtenida para
z
NO es segura de usar porque la instancia temporal se destruirá al final de la expresión completa, antes de llegar a laprintf
declaración. Salida es:fuente