2009-03-26 36 views
14

¿Hay alguna razón por la que pasar una referencia a un mapa STL como const hace que se rompa el operador []? Me sale este error del compilador (gcc 4.2) cuando se utiliza const:C++ const std :: referencia de mapa no se puede compilar

error: no match for ‘operator[]’ in ‘map[name]’

Aquí está el prototipo de la función:

void func(const char ch, std::string &str, const std::map<std::string, std::string> &map); 

Y, debo mencionar que no hay ningún problema cuando quito la const palabra clave delante de std :: map.

Si me han instruido correctamente, el operador [] realmente insertará un nuevo par en el mapa si no encuentra la clave, lo que por supuesto explicaría por qué sucede esto, pero no me puedo imaginar que esto alguna vez sería un comportamiento aceptable.

Si hay un método mejor, como usar encontrar en lugar de [], se lo agradecería. Parece que no puedo encontrar trabajo tampoco ... Recibo const errores de iterador no coincidentes.

Gracias.

Respuesta

26

Sí, no puede usar operator[]. Utilice find, pero tenga en cuenta que vuelve const_iterator en lugar de iterator:

std::map<std::string, std::string>::const_iterator it; 
it = map.find(name); 
if(it != map.end()) { 
    std::string const& data = it->second; 
    // ... 
} 

Es como con los punteros. No puede asignar int const* al int*. Del mismo modo, no puede asignar const_iterator a iterator.

6

Cuando está utilizando el operador [], std :: map busca el elemento con la tecla dada. Si no encuentra ninguno, lo crea. De ahí el problema con const.

Utiliza el método de búsqueda y estarás bien.

¿Puede por favor publicar el código sobre cómo está tratando de usar find()? La forma correcta sería:

if(map.find(name) != map.end()) 
{ 
    //... 
} 
2

Probablemente porque no hay ningún operador const [] en std :: mapa. operator [] agregará el elemento que está buscando si no lo encuentra. Por lo tanto, use el método find() si desea buscar sin la posibilidad de agregar.

2

Para sus "errores de iterador no coincidentes const":

find() tiene dos sobrecargas:

 iterator find (const key_type& x); 
const_iterator find (const key_type& x) const; 

Mi suposición es que usted está recibiendo este error porque estás haciendo algo así como la asignación de un iterador no constante (a la izquierda) con el resultado de una llamada find() en un mapa const:

iterator<...> myIter /* non-const */ = myConstMap.find(...) 

Eso daría lugar a un error, aunque tal vez no sea el que está viendo.

3

Si está utilizando C++ 11, std::map::at debería funcionar para usted.

El motivo por el que std::map::operator[] no funciona es que, en el caso de que la clave que está buscando no exista en el mapa, insertará un nuevo elemento utilizando la clave provista y devolverá una referencia (Ver el enlace para detalles). Esto no es posible en un const std :: map.

El método 'at', sin embargo, lanzará una excepción si la clave no existe. Dicho esto, probablemente sea una buena idea comprobar la existencia de la clave utilizando el método std :: map :: find antes de intentar acceder al elemento utilizando el método 'at'.

Cuestiones relacionadas