2010-05-06 28 views

Respuesta

42

Claro, utilizar un iterador

map<string,Car>::const_iterator it = cars.find(name); 
return it!=cars.end(); 
+5

Como no está mutando 'autos ', es mejor obtener un' const_iterator'. – kennytm

+0

buen punto. Editando ... – Tom

+0

Pero si 'cars' no es const,' cars.find (name) 'devolverá un' iterator' que se debe convertir a 'const_iterator' y' cars.end() 'devolverá un 'iterator' que luego se convertirá en' const_iterator' cuando se lo compara con 'it'. ¿Por qué luchar contra eso? ¿por qué no usar un 'iterator'? –

5
bool exists(const string& name) 
{ 
    return cars.find(name) != cars.end(); 
} 
+0

Haga la función 'const' si es un miembro? –

+1

Si es un miembro, entonces sí. –

70
return cars.find(name) != cars.end(); 
+0

¡Esta es la respuesta que usaría! –

1
bool exists(const std::map<std::string, Car>& cars, const std::string& name) { 
    return cars.end() != cars.find(name); 
} 
+0

¿Por qué no hacerlo aún más genérico convirtiéndolo en una función de plantilla? Pero probablemente no cumplirá con el requisito de elegancia mejor. – foraidt

+0

@mxp, vea mi solución para eso (http://stackoverflow.com/questions/2781899/how-to-find-whether-an-element-exists -en-stdmap/2782084 # 2782084). –

2

std::map::find(const key_type& x);

Devuelve map::end si el artículo no existe.

21

También es posible usar

bool exists(const string& name) { 
    return cars.count(name) != 0; 
} 
+0

'! = 0' opcional. – Potatoswatter

+12

@Potatoswatter Pero deja en claro exactamente qué se está probando. Es un problema puramente estilístico, pero no dependo de las conversiones implícitas int a bool. – KeithB

+4

@Potatoswatter: la comparación explícita suprimiría una advertencia de VC++ ("advertencia de rendimiento: forzando que integer bool");) – UncleBens

7

¿Qué hay de:

template <typename KeyType, typename Collection> 
bool exists_in(Collection const& haystack, KeyType const& needle) { 
    return std::find(haystack.begin(), haystack.end(), needle) != haystack.end(); 
} 

template <typename K, typename V> 
bool exists_in(std::map<K,V> const& haystack, K const& needle) { 
    return haystack.find(needle) != haystack.end(); 
} 

Esto hace exists_in trabajo con cualquier contenedor estándar a través std::find y utilizar una versión especial para std::map ya que ofrece una alternativa de búsqueda más eficiente . Puede agregar especializaciones adicionales según sea necesario (p. Ej., Para std::set y otros).

+4

Pase todo por la referencia constante. – UncleBens

15

Aparte de las respuestas con iterator-Value de find() y comparación con .end(), hay otra manera: map :: count.

Puede llamar a map :: count (key) con una clave específica; devolverá cuántas entradas existen para la clave dada. Para mapas con claves únicas, el resultado será 0 o 1. Como multimap también existe con la misma interfaz, mejor compare con! = 0 para que la existencia sea segura.

por su ejemplo, eso es

return (cars.count(name)>0); 

Las ventajas que veo son 1. código más corto, 2. beneficio de cualquier optimizaciones la biblioteca puede aplicar internamente, usando sus datos de representación.

0
#define itertype(v) typeof((v).begin()) 
itertype(cars) it = cars.find(name); 
return it != cars.end(); 
+0

¿Por qué no usarías 'auto' en lugar de esta macro? 'auto it = cars.find (name);' –

+0

Bienvenido a SO. Esta respuesta realmente no agrega nada nuevo que no esté cubierto en las respuestas existentes (mucho más antiguas). Considere eliminar su respuesta y quizás intente responder a preguntas que aún no tienen respuestas aceptadas. –

Cuestiones relacionadas