c++ - ejemplo - ¿Qué sucede si leo el valor de un mapa donde no existe la clave?
hashmap c++ (7)
El map::operator[]
busca en la estructura de datos un valor correspondiente a la clave dada, y le devuelve una referencia.
Si no puede encontrar uno, crea de forma transparente un elemento construido predeterminado para él. (Si no desea este comportamiento, puede usar la función map::at
).
Puede obtener una lista completa de los métodos de std :: map aquí:
http://en.cppreference.com/w/cpp/container/map
Aquí está la documentación de map::operator[]
del estándar actual de C ++ ...
23.4.4.3 Acceso al elemento del mapa
T& operator[](const key_type& x);
Efectos: si no hay una clave equivalente a x en el mapa, inserta value_type (x, T ()) en el mapa.
Requiere: key_type será CopyConstructible y mapped_type será DefaultConstructible.
Devoluciones: Una referencia al tipo mapped correspondiente a x en * esto.
Complejidad: logarítmica.
T& operator[](key_type&& x);
Efectos: Si no hay una clave equivalente a x en el mapa, inserta value_type (std :: move (x), T ()) en el mapa.
Requiere: mapped_type será DefaultConstructible.
Devoluciones: Una referencia al tipo mapped correspondiente a x en * esto.
Complejidad: logarítmica.
map<string, string> dada;
dada["dummy"] = "papy";
cout << dada["pootoo"];
Estoy desconcertado porque no sé si se considera un comportamiento indefinido o no, cómo saber cuándo solicito una clave que no existe, ¿uso simplemente buscar en su lugar?
El operator[]
para el map
devuelve una referencia no constante y puede asignarlo usando la forma que ha mostrado en su segunda línea. Al acceder de esta manera, se creará un elemento de value
de construcción predeterminado.
Si quieres encontrar un elemento encontrar, una mejor manera es
iterator find ( const key_type& x )
(o la alternativa const) que devolverá un iterador igual a <map>.end()
si no encuentra la clave, o si solo quiere saber si está en la colección, puede usar
size_type count ( const key_type& x ) const
que siempre devolverá 1 o 0 para un mapa ya que las claves son únicas.
No es un comportamiento indefinido. Si el operator []
no encuentra un valor para la clave proporcionada, inserta uno en esa posición.
Para el operador [], si intenta acceder a un valor para una clave que no existe, un nuevo objeto de valor que se haya construido por defecto se colocará en el mapa y se devolverá su referencia.
Si el operador [] no encuentra un valor para la clave proporcionada, inserta uno en esa posición.
Pero debe tener en cuenta que si visita una not exist key
e invoca su función miembro, como mapKV [not_exist_key] .member_fun (). El programa puede bloquearse.
Déjame dar un ejemplo, prueba la clase de abajo:
struct MapValue{
int val;
MapValue(int i=0){
cout<<"ctor: "<<i<<endl; val = i;
}
~MapValue(){
cout<<"dtor: "<<val<<endl;
}
friend ostream& operator<<(std::ostream& out, const MapValue& mv){
cout<<"MapValue: "<<mv.val<<endl;
}
string toString(){
cout<<"MapValue: "<<val<<endl;
}
};
Código de prueba:
cout<<"-------create map<int, MapValue>-------"<<endl;
map<int, MapValue> idName{{1, MapValue(1)}, {2, MapValue(2)}};
cout<<"-----cout key[2]-----"<<endl;
cout<<idName[2]<<endl;
cout<<"-----cout key[5]-----"<<endl;
cout<<idName[5]<<endl;
cout<<"------- runs here means, does''t crash-------"<<endl;
Salida como abajo:
-------create map<int, MapValue>-------
ctor: 1
ctor: 2
dtor: 2
dtor: 1
dtor: 2
dtor: 1
-----cout key[2]-----
MapValue: 2
-----cout key[5]-----
ctor: 0
MapValue: 0
-------runs here means, does''t crash-------
dtor: 0
dtor: 2
dtor: 1
Podemos ver que: idName[5]
invoca la construcción del mapa {5, MapValue(0)}
para insertar en idName.
Pero si invoca la función miembro por idName[5]
, entonces el programa se bloquea:
cout<<"-------create map<int, MapValue>-------"<<endl;
map<int, MapValue> idName{{1, MapValue(1)}, {2, MapValue(2)}};
idName[5].toString(); // get crash here.
cout<<"------- runs here means, does''t crash-------"<<endl;
Si intenta acceder a un key value
utilizando el operador de índice []
, pueden suceder 2 cosas:
- El mapa contiene esta
key
. Así se devolverá elkey value
correspondiente. - El mapa no contiene la
key
. En este caso, agregará automáticamente unakey
al mapa connull value
.
"pootoo"
clave "pootoo"
existe en tu mapa. Entonces, automáticamente agregará esta key
con el value = ""
(cadena vacía). Y su programa imprimirá una cadena vacía.
Aquí el tamaño del mapa aumentará en 1
.
Para buscar una clave puede usar map_name.find()
, que devolverá map_name.end()
si la clave no existe. Y no se agregará ninguna key
adicional.
Puede utilizar el operador []
cuando desee establecer el valor de una clave.
por favor, eche un vistazo a la excepción out_of_range: http://www.cplusplus.com/reference/stdexcept/out_of_range/
esto es lo que map :: at y map :: operator [] lanzarán si la clave no existe. Puede capturarlo de la misma manera que el ejemplo de vector en el enlace.
También puede utilizar: http://www.cplusplus.com/reference/map/map/find/
Y verifica contra mapa :: fin