c++ - reales - ¿Por qué se llama al constructor de referencia de valor r en este caso?
libro de android studio en español pdf (2)
La elisión de copia está relacionada con A, no está construida en el marco de pila get (). Lo que ocurre es que la b
devuelta (que es temporal dado que "va a morir debido a un retorno": esto es desde C ++ 14), se usa para construir la A
en el marco de la pila principal.
Y dado que los objetos temporales se unen a las referencias de valor r, eso es lo que observaste.
#include<iostream>
using namespace std;
struct B{};
struct A
{
A(const B &)
{
cout<<"A(const B &)"<<endl;
}
A(B &&)
{
cout<<"A(B &&)"<<endl;
}
};
A get()
{
B b;
return b;
}
int main()
{
get();
}
Probé el código con VC ++ 14.2 y GCC 5.4.0, ambos emitidos:
A(B &&)
¿Por qué el resultado no es
A(const B &)
?
¿Tiene este código alguna relación con la copy elision
? (Pero A y B son tipos diferentes, por lo que la copy elision
no debería funcionar aquí)
Las reglas return-as-rvalue cambiaron en respuesta a la revisión antes de la publicación de C ++ 14. El cambio se agregó al final del proceso y es capturado por CWG1579 , que enmienda 12.8 / 32 con la siguiente redacción:
o cuando la expresión en una declaración
return
es una expresión id (posiblemente entre paréntesis) que nombra un objeto con una duración de almacenamiento automática declarada en el cuerpo
Esto significa que devolver cualquier variable local ahora considera el objeto designado por esa variable como si fuera un valor r primero (lo intenta de nuevo si falla la resolución de sobrecarga).
Dado que el problema del CWG fue aceptado como un defecto en el lenguaje, los compiladores pueden implementar esta nueva regla incluso en el "modo C ++ 11". El punto de un defecto es que "siempre se pretendía que funcionara de esa manera", por lo que no se trata estrictamente de un cambio entre C ++ 11 y C ++ 14, sino que se modificó el significado de C ++ 11 en 2014.