Voy a responder a su pregunta ... al revés.
¿Por qué permitieron Foo const& foo = fooByValue();
para comenzar?
Hace la vida (algo) más fácil, pero introduce un comportamiento indefinido potencial en todo el lugar.
Foo const& fooByReference()
{
return fooByValue(); // error: returning a reference to a temporary
}
Esto es obviamente erróneo, y de hecho el compilador diligentemente informar de ello. Según el comentario de Tomalak: no es un mandato de la norma, pero los buenos compiladores deben informarlo. Clang, gcc y MSVC sí. Creo que Comeau y icc también lo harían.
Foo const& fooByIndirectReference()
{
Foo const& foo = fooByValue(); // OK, you're allowed to bind a temporary
return foo; // Generally accepted
}
Esto está mal, pero es más sutil. El problema es que la vida útil del temporal está ligada a la duración de foo
, que sale del alcance al final de la función. Una copia de foo
se pasa a la persona que llama, y esta copia apunta al éter.
Repliqué el error en Clang, y Argyris pudo diagnosticar este caso (felicitaciones realmente: p).
Foo const& fooForwarder(Foo const&); // out of line implementation which forwards
// the argument
Foo const& fooByVeryIndirectReference()
{
return fooForwarder(fooByValue());
}
El temporal creado por fooByValue
está obligado a la vida útil del argumento de fooForwarder
, que diligentemente proporcionar una copia (de la referencia), copia que se devuelve a la persona que llama, a pesar de que ahora apunta en el éter .
El problema aquí es que la implementación de fooForwarder
está perfectamente bien con el estándar y, sin embargo, crea un comportamiento indefinido en la persona que llama.
Sin embargo, el hecho desalentador es que diagnosticar esto requiere conocer la implementación de fooForwarder
, que está fuera del alcance del compilador.
La única solución que puedo comprender (aparte de WPA) es una solución de tiempo de ejecución: cada vez que un temporal se limita a una referencia, debe asegurarse de que la referencia devuelta no comparte la misma dirección ... y luego Qué ? assert
? plantear una excepción? Y dado que es solo una solución de tiempo de ejecución, claramente no es satisfactoria.
La idea de vincular temporalmente a una referencia es frágil.
¿No es esta la misma pregunta discutida por Herb Sutter aquí http://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/? – DumbCoder
@DumbCoder: no, Herb Sutter diseña los usos wrt para el estándar C++, mientras que Fred analiza la razón de ser del estándar. –