La elisión de copia ocurre solo cuando una copia no es realmente necesaria. En particular, es cuando hay un objeto (llámelo A) que existe durante la ejecución de una función, y un segundo objeto (llámelo B) que se copiará desde el primer objeto, y inmediatamente después , A se destruirá (es decir, al salir de la función).
En este caso muy específico, la norma otorga permiso para que el compilador combine A y B en dos formas distintas de referirse al mismo objeto.En lugar de requerir que A sea creado, entonces B será una copia construida desde A, y luego A será destruida, permite que A y B se consideren dos formas de referirse al mismo objeto, por lo que el (uno) objeto se crea como A, y después de que la función devuelve comienza a llamarse B, pero incluso si el constructor de la copia tiene efectos secundarios, la copia que crea B de A todavía puede omitirse. Además, tenga en cuenta que en este caso A (como un objeto separado de B) tampoco se destruye, por ejemplo, si su dtor también tuviera efectos secundarios, también podrían (podrían) omitirse.
Su código no se ajusta a ese patrón: el primer objeto no deja de existir inmediatamente después de ser utilizado para inicializar el segundo objeto. Después de F()
devuelve, hay dos instancias del objeto. Siendo ese el caso, la Optimización del Valor de Retorno [Nombrado] (también conocida como copia elisión) simplemente no se aplica.
código de demostración cuando se aplicaría copia elisión:
#include <iostream>
struct foo {
foo(): a(5) { }
foo(const foo& f): a(f.a) { std::cout << "meep meep!\n"; }
int a;
};
int F() {
// RVO
std::cout << "F\n";
return foo();
}
int G() {
// NRVO
std::cout << "G\n";
foo x;
return x;
}
int main() {
foo a = F();
foo b = G();
return 0;
}
Tanto MS VC++ y g ++ optimizar la distancia tanto copiar ctors de este código con la optimización activada. g ++ optimiza ambas cosas, incluso si la optimización está desactivada. Con la optimización desactivada, VC++ optimiza la devolución anónima, pero utiliza el copiador para la devolución especificada.
¿Está preguntando por qué se llama al constructor de copia en lugar de simplemente devolver el valor del campo de la instancia original? –
¿Cómo sabes que no fue eliminado? ¿Y por qué crees que debería haber sido? Por favor, modifique su pregunta con respecto a estas dos consultas. –
@Michael, eso es correcto. –