2011-02-27 11 views
61

He intentado utilizar el operador [] para acceder al elemento en un mapa const C++, pero este método ha fallado. También traté de usar "at()" para hacer lo mismo. Funcionó esta vez. Sin embargo, no pude encontrar ninguna referencia sobre el uso de "at()" para acceder al elemento en un mapa const C++. ¿Está "at()" una función recién agregada en el mapa C++? ¿Dónde puedo encontrar más información sobre esto? ¡Muchas gracias!C++ const acceso a elemento de mapa

Un ejemplo podría ser el siguiente:

#include <iostream> 
#include <map> 

using namespace std; 

int main() 
{ 
     map<int, char> A; 
     A[1] = 'b'; 
     A[3] = 'c'; 

     const map<int, char> B = A; 

     cout << B.at(3) << endl; // it works 
     cout << B[3] << endl; // it does not work 

} 

Para el uso de "B [3]", volvió los siguientes errores durante la compilación:

t01.cpp:14: error: passing ‘const std::map, std::allocator > >’ as ‘this’ argument of ‘_Tp& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&) [with _Key = int, _Tp = char, _Compare = std::less, _Alloc = std::allocator >]’ discards qualifiers

El compilador utilizado es g ++ 4.2.1

Respuesta

80

at() es un nuevo método para std::map en C++ 11.

En lugar de insertar un nuevo elemento construido por defecto como operator[] hace si un elemento con la clave dada no existe, arroja una excepción std::out_of_range. (Esto es similar al comportamiento de at() para deque y vector.)

Debido a este comportamiento tiene sentido que haya una sobrecarga de constat(), a diferencia de operator[] que siempre tiene el potencial de cambiar el mapa.

+0

¿Es posible que "at" devuelva un valor predeterminado en lugar de arrojar una excepción? – user1202136

+0

'at()' debería ser C++ 11 solamente – Deqing

+0

Estoy usando 'at()' con en VS2013 en un proyecto para usar el kit de herramientas VS2010. Pensé que eso significaba que no estaba usando C++ 11 ... ¿Pero compila ...? – thomthom

27

Si un elemento no existe en un map, lo agregará operator [], lo que obviamente no puede funcionar en un mapa const así que C++ no define una versión const del operador. Este es un buen ejemplo del verificador de tipos del compilador que evita un posible error de tiempo de ejecución.

En su caso, es necesario utilizar find vez que única devolver un (iterador a la) elemento si es que existe, nunca se modificará el map. Si un elemento no existe, devuelve un iterador al end() del mapa.

at no existe y ni siquiera debería compilarse. Tal vez esta es una "extensión de compilación" (= un error nuevo en C++ 0x).

+0

¿El estándar de C++ prohíbe que la implementación defina funciones adicionales de miembros no estándares en las clases de la biblioteca? –

+0

@Tim Creo que la interfaz es fija, sí. –

3

El operador [] creará una nueva entrada en el mapa si la clave proporcionada no existe. Por lo tanto, puede cambiar el mapa.

Ver esto link.