Extensión de vida temporal y conversión implícita a una referencia constante

Oct 06 2020

Normalmente, vincular un temporal a un local const&extiende la vida útil del temporal hasta el final del alcance de la referencia:

struct Foo { void DoSomething() const; };
Foo Make();

const Foo& foo = Make(); // compiles
foo.DoSomething(); // ok, lifetime of foo was extended

Pero cuando se trata de una conversión implícita, este ya no es el caso:

struct Foo { void DoSomething(); };
struct Bar { operator const Foo&() const; };
Bar Make();

const Foo& foo = Make(); // compiles calling the implicit conversion operator
foo.DoSomething(); // not ok, temporary Bar has been destroyed

¿Es esto realmente lo que se especifica en el estándar C ++? ¿Es esto intencionado? ¿Es legal declarar operadores de conversión implícitos en a const&? (Otra pregunta es cómo se debe implementar ese operador de conversión. En este caso, sería necesario reinterpret_castconfiar en una representación binaria compatible Fooy Bartenerla, lo que probablemente sea un comportamiento indefinido. En C ++ 20, probablemente se bit_castpodría usar a? suponga Fooderivado de Bar, a static_castpodría usarse, eliminando el comportamiento indefinido y la situación no cambia).

Respuestas

songyuanyao Oct 06 2020 at 14:25

¿Es esto intencionado?

Si. La vida útil de temporal Barno se extenderá a la vida útil de foo.

En general, la vida útil de un temporal no puede extenderse más "pasándolo": una segunda referencia, inicializada a partir de la referencia a la que estaba vinculado el temporal, no afecta su vida útil.

Eso significa que se ampliaría la vida útil del enlace temporal a la referencia directa. En este caso, el temporal Bardevuelto por Make()no está vinculado foodirectamente a.