c++ reference language-lawyer placement-new

¿Las referencias de "reconsolidación" en C++ son legales?



reference language-lawyer (3)

Creo que encontré la respuesta en un pasaje por debajo del "citado" que habla de efectos secundarios dtor / dtor triviales, a saber [basic.life] / 7:

Si, una vez finalizado el tiempo de vida de un objeto y antes de que se reutilice o libere el almacenamiento que ocupa el objeto, se crea un nuevo objeto en la ubicación de almacenamiento ocupada por el objeto original, un puntero que apunta al objeto original, una referencia que referido al objeto original, o el nombre del objeto original se referirá automáticamente al nuevo objeto y, una vez que se haya iniciado el tiempo de vida del nuevo objeto, se puede usar para manipular el nuevo objeto, si:

  • el almacenamiento para el nuevo objeto se superpone exactamente a la ubicación de almacenamiento que ocupó el objeto original, y

  • el nuevo objeto es del mismo tipo que el objeto original (ignorando los cv-qualifiers de nivel superior), y

  • el tipo del objeto original no es const-calificado, y, si es un tipo de clase, no contiene ningún miembro de datos no estático cuyo tipo es const-calificado o un tipo de referencia, y

  • el objeto original era el objeto más derivado del tipo T y el nuevo objeto es el más derivado del tipo T (es decir, no son subobjetos de clase base).

Al reutilizar el almacenamiento, finalizamos la vida útil del objeto original [basic.life] / 1

La vida útil de un objeto de tipo T finaliza cuando:

  • si T es un tipo de clase con un destructor no trivial, se inicia la llamada al destructor, o

  • el almacenamiento que ocupa el objeto se reutiliza o libera.

Así que creo que [basic.life] / 7 cubre la situación

Reference<int> r(x); new (&r) Reference<int>(y);

donde terminamos la vida útil del objeto denotado por r , y creamos un nuevo objeto en la misma ubicación.

Como Reference<int> es un tipo de clase con un miembro de datos de referencia, los requisitos de [basic.life] / 7 no se cumplen. Es decir, r puede que ni siquiera se refiera al nuevo objeto, y no podemos usarlo para "manipular" este objeto recién creado (interpreto este "manipular" también como accesos de solo lectura).

¿Es legal lo siguiente en C ++?

Por lo que puedo decir, Reference tiene un destructor trivial, por lo que debería ser legal.
Pero pensé que las referencias no pueden ser recuperadas legalmente ... ¿o sí?

template<class T> struct Reference { T &r; Reference(T &r) : r(r) { } }; int main() { int x = 5, y = 6; Reference<int> r(x); new (&r) Reference<int>(y); }


No estás volviendo a vincular una referencia, estás creando un nuevo objeto en la memoria de otro con una ubicación nueva. Como el destructor del objeto antiguo nunca se ejecutó, creo que esto sería un comportamiento indefinido.


No hay referencia de rebote en su ejemplo. La primera referencia (construida en la línea dos con el nombre rr ) está vinculada al int denotado por x durante toda su vida útil. La duración de esta referencia finaliza cuando la nueva expresión de ubicación en la línea tres reutiliza el almacenamiento de su objeto que lo contiene. El objeto de reemplazo contiene una referencia que está ligada durante toda su vida, la cual dura hasta el final de su alcance: el final de main .