example - C++ 11: ¿Es seguro eliminar elementos individuales de std:: unordered_map mientras se itera?
unordered_map c++ example (1)
Considere el algoritmo canónico para eliminar un elemento de un contenedor asociativo mientras itera:
for (auto iter = myMap.begin(); iter != myMap.end(); )
{
if (/* removal condition */)
{
iter = myMap.erase(iter);
}
else
{
++iter;
}
}
He estado aplicando este algoritmo sin pensarlo dos veces cuando uso el contenedor C ++ 11 std::unordered_map
. Sin embargo, después de examinar la documentación de std::unordered_map::erase
unordered_map std::unordered_map::erase
en cppreference.com , me preocupó un poco después de leer la siguiente nota:
Se conserva el orden de los elementos que no se borran (esto permite borrar elementos individuales mientras se itera a través del contenedor) (desde C ++ 14)
En base a esta afirmación, supongo que se agregó un lenguaje al estándar C ++ 14 para garantizar que los implementadores de bibliotecas garanticen el pedido después de una llamada a std::unordered_map::erase
. Por ejemplo, tal requisito tal vez constriñe la implementación de no volver a procesar todo el contenedor después de eliminar un elemento, sino que solo le permite eliminar el elemento de su categoría correspondiente.
Sin esa garantía en C ++ 11, y si deseo que mi código sea portátil, ¿tengo que preocuparme de que algunos elementos se visitarán varias veces o no se eliminarán si elimino un elemento de un std::unordered_map
durante la iteración? ?
Editar: los peligros de NoScript. Tenía funcionando noscript, que mostraba las pestañas C11 y C14 como una caja. La respuesta de Praetorian es correcta acerca de que se garantice en la práctica y se formalice en c14.
** A continuación está mal debido a noscript.
En la parte inferior de cplusplus dice que
Solo los iteradores y las referencias a los elementos eliminados quedan invalidados.
El resto no se ven afectados.
El orden relativo de iteración de los elementos no eliminados por la operación se conserva.
http://www.cplusplus.com/reference/unordered_map/unordered_map/erase/
En la parte superior de la página, indica que es para C ++ 11 ... así que a menos que lo hayan actualizado para C ++ 14, creo que también se aplica a C ++ 11. Praetorian debería poner una respuesta y deberías consultar la respuesta de él, porque incluso si no está garantizado en el estándar para C ++ 11 (C ++ 14 es el parche para este tipo de cosas), está garantizado en la práctica.
No pude encontrar el estándar STL, parece haberlo perdido, o iría a ver si había un texto garantizado que pudiera señalar. : - /