¿Se garantiza que unique_ptr almacene nullptr después del movimiento?

78

¿Está unique_ptrgarantizado almacenar nullptrtras mudanza?

std::unique_ptr<int> p1{new int{23}};
std::unique_ptr<int> p2{std::move(p1)};
assert(!p1); // is this always true?
lizarisk
fuente
2
Técnicamente, el estado en el que ::movesale un elemento no está especificado. Tampoco creo que haya ninguna garantía en el extremo del puntero inteligente. Dicho esto, dejaré que los expertos del CPP respondan :)
Benjamin Gruenbaum
1
Espera, no importa, sí. Release lo establece explícitamente en nullptr. Esto está garantizado porunique_ptr
Benjamin Gruenbaum
gcc 4.8.1 aquí, p1 es nulo después de std :: move
Excepcional el
1
Consulte cualquier referencia en std::unique_ptr::operator:y std::unique_ptr::release.
rubenvb
solo mira la semántica de movimiento ...
Deduplicador

Respuestas:

70

Sí, puede compararlo con nullptrdespués del movey se garantiza que se comparará igual.

De §20.8.1 / 4 [unique.ptr]

Además, upuede, previa solicitud, transferir la propiedad a otro puntero único u2. Una vez completada dicha transferencia, se cumplen las siguientes condiciones posteriores:
- u2.pes igual a la pretransferencia u.p,
- u.pes igual anullptr , y
...

(el miembro pse describió anteriormente como: un puntero único es un objeto uque almacena un puntero a un segundo objetop )

Pretoriano
fuente
Esto es claramente cierto después de llamar a release (). Pero std :: move no llama a release (). Entonces, ¿cómo sabe el compilador restaurar el invariante de unique_ptr?
mabraham
1
@mabraham p2{std::move(p1)}es mover la construcción p2de p1. Esa es la transferencia de propiedad solicitada en el texto que cité anteriormente. La implementación del constructor de movimientos se asegurará de que se cumplan todas las condiciones posteriores.
Pretoriano
Gracias. Reformulación: el uso del constructor de movimientos solicita la transferencia de propiedad, y eso debe mantener el invariante de p1. std :: move solo habilita el uso del constructor move.
mabraham
10

Si. De la sección 20.7.1 / 4 estándar de C ++ 2011 :

Además, puede, previa solicitud, transferir la propiedad a otro puntero único u2. Una vez completada dicha transferencia, las siguientes condiciones posteriores mantienen [...] [la fuente unique_ptr] es igual a nullptr ...

Paul Evans
fuente