Estoy un poco confundido por la semántica de std::map::insert
. Quiero decir, no me quejo, el estándar es el estándar y el API es lo que es. Aún así,Justificación de la semántica de inserción de mapas estándar de C++
insert
voluntad
los controles de operación de inserción para cada elemento insertado si existe otro elemento que ya están en el recipiente con el mismo valor de clave , de ser así, el elemento no se ha insertado y su valor mapeado no es cambiado de ninguna manera.
Y - sólo en su versión de un solo argumento pair<iterator,bool> insert (const value_type& x);
será incluso le dirá si es que inserta el valor (nueva, posiblemente diferente) a la llave (s). Por lo que yo entiendo, las versiones del iterador ignorarán silenciosamente las inserciones si la clave ya existe.
Para mí, esto es simplemente contrario a la intuición, Hubiera esperado que la parte de valor se sobrescribiera y la parte de valor anterior fuera descartada en la inserción. Obviamente, los diseñadores de STL pensaban de manera diferente: ¿alguien sabe la razón (histórica) o puede dar una explicación detallada de cómo la semántica existente tiene (más) sentido?
Por ejemplo:
Hay algunas formas básicas para implementar inserto en un mapa de clave única como std::map
:
- insertar, reemplazar si ya existe
- inserción, ignorar si ya existe (este es el comportamiento de std :: map)
- insertar, lanzar error si ya existe
- inserción, UB, si ya existe
Ahora estoy tratando de entender por qué insert_or_ignore
tiene más sentido que insert_or_replace
(o insert_or_error
)!
mirase en mi copia de TC++PL (por desgracia sólo tengo la edición alemana), y curiosamente, BS escribe en el capítulo 17.4.1.7 (operaciones de lista de mapa): (traducción aproximada siento del alemán)
(...) Por lo general, uno no le importa si una clave (sic) es de reciente insertado o ya existía antes de la llamada a
insert()
(...)
Lo cual, me parece, solo sería válido para conjunto, y no para mapa, porque para un mapa, si el valor proporcionado se insertó o el anterior permanece en el mapa, sí hay alguna diferencia . (Obviamente no importa la clave, ya que esa es equivalente.)
Nota: Sé acerca operator[]
y sé acerca del artículo 24 de la Effective STL y no propuso efficientAddOrUpdate
función. Solo tengo curiosidad por un razonamiento en la semántica de insert
porque, personalmente, les encuentro contra la intuición.
Bueno, no le pidió que modificar un valor existente, se le solicitará que insertar un (nuevo) valor. Estoy de acuerdo en que reportar fallas más consistentemente hubiera sido algo bueno. Aún puede desreferenciar el iterador devuelto y verificar si el nuevo valor o uno anterior está presente, o incluso usar ese iterador para actualizar el valor existente. –
Si desea reemplazar/crear, use el operador '[]'. – BoBTFish
Aquí hay un código para ["insertar con fuerza"] (http://stackoverflow.com/a/8337563/596781) en un mapa. –