Todos los casos son correctos. Todos construirán un temporal y aplicarán el constructor de copia del tipo de devolución. Necesariamente, si no hay un constructor de copia, el código fallará.
RVO sucederá en los tres casos en la mayoría de los compiladores. La única diferencia es la última donde el estándar no lo fuerza. Esto porque tienes una variable con nombre. Pero la mayoría de los compiladores son lo suficientemente inteligentes como para aplicar RVO a él ... cuanto más tarde se declare la variable nombrada y menos transformaciones se aplique, mejores serán las probabilidades de que se aplique RVO a una variable con nombre.
Dicho sea de paso, es posible devolver una referencia como posiblemente haya visto en otro código. Lo que no debes hacer es devolver una referencia a un objeto local.
std::string& get_a_string2()
{
std::string str("hello");
return str; //error!
}
Producirá un error de tiempo de compilación, como usted sabe. Sin embargo,
std::string& get_a_string2(std::string& str)
{
// do something to str
return str; //OK
}
Funcionará bien. En este caso, no hay construcción de construcción o copia involucrada. Simplemente la función devuelve una referencia a su argumento.
¿Hay alguna forma en VS2008 de desactivar todas las optimizaciones, incluido RVO? He apagado todo, pero todavía está haciendo RVO. Esto es solo para entender las diferencias. –
'/ Od' debe deshabilitar NRVO, pero no estoy seguro acerca de RVO. –
Gracias. Déjame probar eso –