mapa example ejemplo cplusplus c++ c++11 c++14 stdmap

c++ - example - mapa cplusplus



¿Cómo evitar el reparto constante para el acceso al mapa? (2)

Tengo el siguiente problema:

std::map<A*,double> map; void getColor(A const * obj){ double d = map[obj]; // does not compile wihtout const_cast<A*>(obj) // do something }

Tengo un mapa std::map (en algún lugar) que almacena los punteros a los objetos A Tengo una función getColor que no manipula los objetos A y, por lo tanto, lleva un puntero a una const A como entrada.

La función getColor no se compilará sin utilizar un const_cast.

El lanzamiento constante es un problema de diseño, pero no sé cómo evitarlo si no quiero hacer que las claves en el map constantes .

Cualquier ayuda apreciada.


Hay dos posibles escenarios aquí:

  1. La función sabe / espera que obj ya esté presente en el mapa, y está usando [] para su comodidad.

  2. Está utilizando [] para todo su potencial, es decir, espera que agregue obj al mapa si no está ya allí.

En la situación 2, tienes un error en la firma getColor . Dado que potencialmente puede pasar obj a un lugar donde se almacenará como A* , es incorrecto que acepte una const A* solamente. Tenga en cuenta que incluso si una función no modifica un objeto en sí, sino que lo pasa a algún lugar donde pueda modificarse, en realidad lo está modificando indirectamente y, por lo tanto, debería tomarlo como no const .

En la situación 1, depende de tu versión de C ++. C ++ 14 introdujo una sobrecarga de plantillas de find y funciones miembro relacionadas de std::map que toman cualquier cosa comparable con Key lugar de solo Key . Por lo tanto, podría modificar la función de esta manera:

void getColor( A const * obj){ doubel d = map.find(obj)->second; // do something }

Tenga en cuenta que para que esto funcione, también necesita cambiar el tipo de mapa para usar un comparador transparente: std::map<A*,double, std::less<>> map; (como lo señaló por primera vez la respuesta de @Ley ).

Si estás atascado con C ++ 11 o anterior, estás fuera de suerte y tendrás que vivir con const_cast . Tenga en cuenta que con un comentario adecuado, un const_cast es perfectamente seguro y aceptable en este caso (sin mencionar la única manera de proceder sin cambiar el tipo de map ). De nuevo, debe usar find o quizás at lugar de [] , ya que no desea insertar en el mapa.


Si puede permitirse cambiar a C ++ 14, puede configurar su mapa para que use un comparador transparente (esto funcionará ya que un puntero de const puede compararse con un puntero de no const):

std::map<A*,double, std::less<>> map; // ^^^^^^^^^^^ // enable transparent comparator on this map void getColor( A const * obj){ auto it = map.find(obj); assert(it != map.end()); double d = it->second; // do something }

Tenga en cuenta que deberá usar std::map::find() lugar de std::map::operator[] , ya que este último no tiene una versión transparente .