c++ - tag - ¿Reutilizando un contenedor movido?
para que es el tag manager (3)
De la sección 17.3.26 de la especificación "estado válido pero no especificado":
un estado de objeto que no se especifica excepto que las invariantes del objeto se cumplen y las operaciones en el objeto se comportan según lo especificado para su tipo [Ejemplo: si un objeto
x
del tipostd::vector<int>
está en un estado válido pero no especificado,x.empty()
se puede llamar incondicionalmente, y se puede llamar ax.empty()
solo six.empty()
devuelve falso. -Final ejemplo]
Por lo tanto, el objeto es en vivo. Puede realizar cualquier operación que no requiera una condición previa (a menos que primero verifique la precondición).
clear
, por ejemplo, no tiene condiciones previas. Y devolverá el objeto a un estado conocido. Así que simplemente límpialo y úsalo como de costumbre.
¿Cuál es la forma correcta de reutilizar un contenedor movido?
std::vector<int> container;
container.push_back(1);
auto container2 = std::move(container);
// ver1: Do nothing
//container2.clear(); // ver2: "Reset"
container = std::vector<int>() // ver3: Reinitialize
container.push_back(2);
assert(container.size() == 1 && container.front() == 2);
De lo que he leído en el borrador estándar de C ++ 0x; ver3 parece ser la forma correcta, ya que un objeto después del movimiento está en una
"A menos que se especifique lo contrario, dichos objetos trasladados se colocarán en un estado válido pero no especificado".
Nunca he encontrado ninguna instancia donde esté "especificado de otra manera".
Aunque encuentro que ver3 es un poco indirecto y preferiría mucho ver1, aunque vec3 puede permitir algunas optimizaciones adicionales, pero por otro lado puede conducir fácilmente a errores.
¿Mi suposición es correcta?
El objeto que se muestra en un estado válido pero no definido básicamente significa que, aunque el estado exacto del objeto no está garantizado, es válido y, como tal, se garantiza que las funciones de los miembros (o funciones no miembros) funcionarán siempre que no confíen en el objeto que tiene un cierto estado.
La función de miembro clear()
no tiene condiciones previas para el estado del objeto (otras, por lo tanto, es válido, por supuesto) y, por lo tanto, puede invocarse desde objetos. Por otro lado, por ejemplo, front()
depende de que el contenedor no esté vacío y, por lo tanto, no se puede llamar, ya que no se garantiza que esté vacío.
Por lo tanto, tanto ver2 como ver3 deberían estar bien.
No creo que puedas hacer NADA con un objeto movido (excepto destruirlo).
¿No puede usar swap
lugar, para obtener todas las ventajas de moverse pero dejar el contenedor en un estado conocido?