versiones guia español actualizar c++ stl map

c++ - guia - qgis español



¿Determinar si el mapa contiene un valor para una clave? (9)

¿Cuál es la mejor manera de determinar si un mapa STL contiene un valor para una clave dada?

#include <map> using namespace std; struct Bar { int i; }; int main() { map<int, Bar> m; Bar b = {0}; Bar b1 = {1}; m[0] = b; m[1] = b1; //Bar b2 = m[2]; map<int, Bar>::iterator iter = m.find(2); Bar b3 = iter->second; }

Al examinar esto en un depurador, parece que iter es solo datos basura.

Si me despido de esta línea:

Bar b2 = m[2]

El depurador muestra que b2 es {i = 0} . (Supongo que significa que el uso de un índice no definido devolverá una estructura con todos los valores vacíos / sin inicializar)

Ninguno de estos métodos es tan grande. Lo que realmente me gustaría es una interfaz como esta:

bool getValue(int key, Bar& out) { if (map contains value for key) { out = map[key]; return true; } return false; }

¿Existe algo en este sentido?


¿Existe algo en este sentido?

No. Con la clase de mapa stl, utiliza ::find() para buscar en el mapa y compara el iterador devuelto con std::map::end()

asi que

map<int,Bar>::iterator it = m.find(''2''); Bar b3; if(it != m.end()) { //element found; b3 = it->second; }

Obviamente, puedes escribir tu propia rutina getValue() si quieres (también en C ++, no hay razón para usarla), pero sospecho que una vez que aprendas a usar std::map::find() ganaste. No quiero perder tu tiempo.

También su código es ligeramente incorrecto:

m.find(''2''); buscará en el mapa un valor clave que sea ''2'' . IIRC el compilador de C ++ convertirá implícitamente ''2'' a un int, lo que da como resultado el valor numérico para el código ASCII para ''2'' que no es lo que se desea.

Ya que su tipo de clave en este ejemplo es int usted desea buscar así: m.find(2);


Acabo de darme cuenta que con C++20 tendremos

std::map::contains( const Key& key ) const;

Eso devolverá verdadero si el mapa contiene un elemento con clave key .


Boost Multindex se puede utilizar para una solución adecuada. La siguiente solución no es la mejor opción, pero puede ser útil en algunos casos en los que el usuario asigna un valor predeterminado como 0 o NULL en la inicialización y desea verificar si el valor se ha modificado.

Ex. < int , string > < string , int > < string , string > consider < string , string > mymap["1st"]="first"; mymap["second"]=""; for (std::map<string,string>::iterator it=mymap.begin(); it!=mymap.end(); ++it) { if ( it->second =="" ) continue; }


Compruebe el valor de retorno de find contra end .

map<int, Bar>::iterator it = m.find(''2''); if ( m.end() != it ) { // contains ... }


Puedes crear tu función getValue con el siguiente código:

bool getValue(const std::map<int, Bar>& input, int key, Bar& out) { std::map<int, Bar>::iterator foundIter = input.find(key); if (foundIter != input.end()) { out = foundIter->second; return true; } return false; }


Si desea determinar si una clave está en el mapa o no, puede usar la función miembro find () o count () del mapa. La función de búsqueda que se usa aquí en el ejemplo devuelve el iterador a element o map :: end de lo contrario. En caso de conteo, el conteo devuelve 1 si se encuentra, de lo contrario, devuelve cero (o lo contrario).

if(phone.count(key)) { //key found } else {//key not found } for(int i=0;i<v.size();i++){ phoneMap::iterator itr=phone.find(v[i]);//I have used a vector in this example to check through map you cal receive a value using at() e.g: map.at(key); if(itr!=phone.end()) cout<<v[i]<<"="<<itr->second<<endl; else cout<<"Not found"<<endl; }


Siempre que el mapa no sea un multimapa, una de las formas más elegantes sería utilizar el método de conteo.

if (m.count(key)) // key exists

El recuento sería 1 si el elemento está presente en el mapa.


Ya existe con encontrar solo no en esa sintaxis exacta.

if (m.find(2) == m.end() ) { // key 2 doesn''t exist }

Si desea acceder al valor si existe, puede hacerlo:

map<int, Bar>::iterator iter = m.find(2); if (iter != m.end() ) { // key 2 exists, do something with iter->second (the value) }

Con C ++ 0x y auto, la sintaxis es más simple:

auto iter = m.find(2); if (iter != m.end() ) { // key 2 exists, do something with iter->second (the value) }

Le recomiendo que se acostumbre a él en lugar de intentar crear un nuevo mecanismo para simplificarlo. Es posible que pueda reducir un poco de código, pero considere el costo de hacerlo. Ahora ha introducido una nueva función que las personas familiarizadas con C ++ no podrán reconocer.

Si desea implementar esto de todos modos a pesar de estas advertencias, entonces:

template <class Key, class Value, class Comparator, class Alloc> bool getValue(const std::map<Key, Value, Comparator, Alloc>& my_map, int key, Value& out) { typename std::map<Key, Value, Comparator, Alloc>::const_iterator it = my_map.find(key); if (it != my_map.end() ) { out = it->second; return true; } return false; }


amap.find devuelve amap::end cuando no encuentra lo que está buscando, se supone que debe verificarlo.