¿Cómo verificar si std :: map contiene una clave sin insertar?

148

La única forma en que he encontrado para verificar si hay duplicados es insertando y comprobando std::pair.secondpara false, pero el problema es que esto todavía inserta algo si la clave no se usa, mientras que lo que quiero es una map.contains(key);función.

jmasterx
fuente

Respuestas:

305

Uso my_map.count( key ); solo puede devolver 0 o 1, que es esencialmente el resultado booleano que desea.

Alternativamente my_map.find( key ) != my_map.end()funciona también.

Agua de patata
fuente
40
@John: Eso apesta a optimización prematura. En GCC (y estoy seguro de que los sistemas más razonables), map::countse implementa como find(__x) == end() ? 0 : 1;. Para multimapel puede tener un argumento de rendimiento, pero esa no es la pregunta de OP y todavía prefiero la elegancia.
Potatoswatter
42
No, el argumento de optimización prematura solo es válido si la optimización requiere un esfuerzo que en este caso no es necesario.
markh44
13
No es verdad. No es prematuro si hace que el código sea más fácil de leer o elimina la sobrecarga innecesaria. En este caso, si count () se implementa a través de find () de todos modos, entonces llamar a find () elimina directamente una función call ... ergo, es una optimización madura . Creo que usar la llamada find () también es más obvio, pero esa es una preferencia puramente personal.
Tim Keating
9
No es una optimización prematura conocer el rendimiento de las funciones de la biblioteca antes de acostumbrarse a usarlas. En este caso, tiene razón, no importa, pero tampoco la minúscula diferencia estilística entre encontrar y contar. Creo que lleva demasiado lejos la retórica de la "optimización prematura". Debe tomar cualquier hábito de optimización "gratuito" que pueda encontrar y utilizarlo para el desarrollo diario. Es cuando los codificadores sucumben a la trampa de pagar costos en legibilidad / tiempo de desarrollo / etc., todo por "ganancias de rendimiento" no medidas que la retórica de optimización prematura se convierte en el consejo correcto para dar.
VoidStar
10
Lejos, std solo debería agregar una maldita has(k)/ contains(k)como cualquier otra clase de mapa sensata en el planeta. Mal diseño de la interfaz. El enfoque find () es demasiado detallado y count(k)definitivamente no está en paridad semántica has(k). Para el caso tampoco lo es find(k). Mira el recuento de visitas en esta pregunta.
Jarrod Smith
46

La respuesta de Potatoswatter está bien, pero prefiero usar findo en su lower_boundlugar. lower_boundes especialmente útil porque el iterador devuelto puede usarse posteriormente para una inserción insinuada, si desea insertar algo con la misma clave.

map<K, V>::iterator iter(my_map.lower_bound(key));
if (iter == my_map.end() || key < iter->first) {    // not found
    // ...
    my_map.insert(iter, make_pair(key, value));     // hinted insertion
} else {
    // ... use iter->second here
}
Chris Jester-Young
fuente
Esto es sutilmente diferente de cómo dice que lo está haciendo ... la única diferencia es que valuese puede omitir el cálculo si la inserción es innecesaria.
Potatoswatter
1
Claro, entiendo que al OP no le importa insertar, por lo que una lower_boundsolución basada en es exagerada. Acabo de mencionar mi respuesta "para completar"; como dije, el tuyo es perfectamente adecuado. :-)
Chris Jester-Young
44
Sí, esta es una buena respuesta y no estoy en desacuerdo con nada. Simplemente señalando la relación con la alternativa inserta priori. En realidad, hay otra diferencia si se usa a multimap, el lower_boundmétodo se inserta al comienzo del rango equivalente, mientras que el insertmétodo simple se agrega al final del rango.
Potatoswatter
2
No es la respuesta a la pregunta, pero mi pregunta pobre me lleva a la respuesta correcta aquí ... Necesito hacer la inserción / actualización. : D
Hunter-Orionnoir
1
@ Hunter ¿Puedes mostrarme tu código? Si no es masivo, probablemente pueda revisarlo por usted.
Chris Jester-Young
8

Su deseo map.contains(key)está programado para el borrador del estándar C ++ 2a . En 2017 fue implementado por gcc 9.2 . También está en el sonido actual .

Camille Goudeseune
fuente
¡Esta es una buena característica! Creo que ha aterrizado en C ++ 20. cppreference.com
Franklin Yu