programacion partes objetos copia constructores con clases clase argumentos c++ language-lawyer c++17 copy-elision gcc8

objetos - partes de un constructor en c++



¿El comportamiento de la elección de copia garantizada depende de la existencia del constructor de copia definido por el usuario? (1)

El siguiente código se comporta de manera diferente con o sin el constructor de copias definido por el usuario bajo GCC 8.0.1 :

#include <cassert> struct S { int i; int *p; S() : i(0), p(&i) {} // S(const S &s) : i(s.i), p(&i) {} // #1 // S(const S &s) : i(s.i), p(s.p) {} // #2 // S(const S &s) = delete; // #3 }; S make_S() {return S{};} int main() { S s = make_S(); assert(s.p == &s.i); }

Con cualquiera de los constructores de copia definidos por el usuario comentados (incluso con # 2, el que realiza una copia superficial simple), la afirmación no fallará, lo que significa que la elección de copia garantizada funciona como se espera.

Sin embargo, sin ningún constructor de copia definido por el usuario, la aserción falla, lo que significa que el objeto s en la función main no está construido por defecto. ¿Por qué pasó esto? ¿No se garantiza el rendimiento de la copia aquí?


Cita de C ++ 17 Borrador de trabajo §15.2 Objetos temporales Párrafo 3 ( https://timsong-cpp.github.io/cppwp/class.temporary#3 ):

Cuando un objeto de clase de clase X se pasa o se devuelve desde una función , si cada constructor de copia, mover constructor y destructor de X es trivial o eliminado, y X tiene al menos una copia o constructor de movimiento no eliminado, las implementaciones son permitido para crear un objeto temporal para contener el parámetro de función u objeto de resultado . ... [ Nota : Esta latitud se otorga para permitir que los objetos de tipo de clase se pasen o devuelvan desde las funciones de los registros. - nota final ]

En su caso, cuando hice que tanto los constructores de copiar como mover estuvieran por defecto:

S(const S &) = default; S(S &&) = default;

La afirmación también falló con GCC y Clang. Tenga en cuenta que los constructores definidos de manera implícita son triviales.