std::map, puntero de mapa de valor de la clave, es esto posible?

std::map<std::string, std::string> myMap;

std::map<std::string, std::string>::iterator i = m_myMap.find(some_key_string);
if(i == m_imagesMap.end())
    return NULL;

string *p = &i->first;

Es la última línea válida?
Quiero guardar este puntero p a algún otro lugar, será válida para todo el programa de vida?
Pero, ¿qué pasaría si puedo añadir algunas más elementos a este mapa (con el resto de claves únicas) o quitar algunas otras teclas, no se reasignar esta cadena (par clave-valor), por lo que el p dejarán de ser válidas?

  • respuesta corta: probablemente NO, respuesta larga: no compilar a menos que previamente había utilizado typedef const std::string string; en lugar de using namespace std; que es bastante confuso…
InformationsquelleAutor michael | 2009-02-05

4 Kommentare

  1. 20

    Primero, los mapas están garantizados para ser estable, es decir, los iteradores no se invalidan por el elemento de inserción o deleción (excepto el elemento se elimina de curso).

    Sin embargo, la estabilidad de iterador no garantiza la estabilidad de los punteros! Aunque por lo general, sucede que la mayoría de las implementaciones uso de punteros – al menos en algún nivel – para implementar los iteradores (lo que significa que es bastante seguro asumir que su solución va a trabajar), lo que realmente debería tienda es el iterador de la misma.

    Lo que usted podría hacer es crear un objeto pequeño como:

    struct StringPtrInMap
    {
      typedef std::map<string,string>::iterator iterator;
      StringPtrInMap(iterator i) : it(i) {}
      const string& operator*() const { return it->first; }
      const string* operator->() const { return &it->first; }
      iterator it;
    }

    Y, a continuación, la tienda que en lugar de un puntero de cadena.

    • Gracias, pero necesito pasar un puntero como mensaje de windows LPARAM, puedo emitir iterador para LPARAM y, a continuación, volver a iterador de nuevo?
    • No, pero se puede almacenar el iterador y, a continuación, utilizar &i>la primera, que es la cadena* usted necesita. Como dice Pierre, este debe ser el más portátil de error y solución segura.
    • Hmm .. solo mirando a la otra muy upvoted respuesta. Desde el ets (también) requiere referencias para ser estable, esto significaría también punteros, no sólo de los iteradores, están obligados a ser estable.
  2. 52

    Sección 23.1.2#8 (asociativa requisitos de contenedor):

    La inserción de los miembros no afectará a la validez de los iteradores y referencias en el contenedor, y el borrado de los miembros deberá invalidar sólo iteradores y las referencias a los elementos borrar.

    Así almacenar punteros a miembros de datos de un elemento del mapa que está garantizado para ser válido, a menos que se retire que elemento.

    • En realidad, no tanto … el /iterador/ es estable, pero manteniendo un iterador estable no implica mantener el puntero estable (se podría imaginar un recolector de basura asegurarse de que cada iterador de la traza de los datos, pero no los punteros).
    • Hmmm, parece que está a la derecha. Mientras que el estándar explícitamente hace notas acerca de vector, lista, y deque – cuando las referencias y los iteradores son invalidado, no puedo encontrar nada acerca de/mapa de conjunto de iterador/referencia validez.
    • Greg, los iteradores seguir siendo válido, incluso si usted borrar otros de los iteradores. sólo el iterador que se borra es invalidado por una operación de ese tipo. creo (aunque no tengo ni miró hacia arriba) datos no se mueven alrededor en un mapa. sería bueno si alguien encuentra una cita en esta – o de una cita demostrando mal.
    • sí, Greg, estamos en lo correcto. 23.1.2/8: «La inserción de los miembros no afectará a la validez de los iteradores y referencias en el contenedor, y el borrado de los miembros deberá invalidar sólo iteradores y las referencias a los elementos borrar.» usted obtiene +1 por mí, por supuesto.
    • Gracias por la referencia. No tengo una copia de la norma real, y el proyecto de norma en la web no la tienen. El C++0x proyecto de norma tiene esto en 23.1.4#8
    • He contado una multitud de personas a upvote esta respuesta. Esperemos que hacen burbuja 🙂
    • El texto estándar es un poco raro aquí, hablando sobre «las referencias al contenedor»… También, para C++11 y el desordenada de los contenedores, la intención es similar, y la redacción es más limpio: La inserción y emplace a los miembros no afectará a la validez de las referencias a los elementos del contenedor, pero puede invalidar todos los iteradores para el contenedor. El borrado de los miembros deberá invalidar sólo iteradores y las referencias a los elementos borrar.
    • Sólo para nota: El texto ha sido trasladado a la nueva sección p.744, 23.2.4#9 en la más reciente versión de borrador de estándar. N3797, 2013-10-13

  3. 1

    Si usted no está seguro de que las operaciones de invalidará su iteradores, usted puede mirar hacia arriba con bastante facilidad en el referencia. Por ejemplo, para vector::insert dice:

    De esta forma, aumenta el tamaño del vector, lo que provoca una automática de la reasignación del espacio de almacenamiento si, y sólo si, el nuevo vector de tamaño surpases la corriente, el vector de la capacidad. Las reasignaciones en el vector de contenedores en la anulación de todas obtenido previamente iteradores, referencias y punteros.

    mapa::insert por otro lado no menciona nada de la clase.

    Como Pierre, dijo, se debe almacenar el iterador en lugar de el puntero, aunque.

    • cplusplus.com es una mala fuente para citar ese tipo de cosas. En general, los ejemplos de cplusplus.com son pobres. No estoy diciendo que sólo por diversión, pero yo sé – yo he visto muchas veces. el mejor ejemplo de su mala calidad es cplusplus.com/reference/iostream/ostream/operator%3C%3C.html
    • nada con respecto a su respuesta, aunque. sólo para decirte lo que pienso acerca de ese sitio.
    • Entonces, ¿qué hace usted uso de una referencia, si usted no tiene un libro a la mano? http://www.cppreference.com todavía se siente incompleto.
    • hackingwords. a menudo terminan mirando cplusplus.com para una referencia rápida sobre los nombres de función. para «stl», me veo en la SGI sitio, que me parece muy buena. no documento c++ arroyos y otros que no estaba en el SGI de la stl, así que me veo en cplusplus.com para aquellos.
    • pero yo no recomendaría usted a confiar en sus ejemplos, o incluso aprender de ella. he visto demasiados casos en los que oversimplificates cosas o incluso está mal (como en mi ejemplo, dicen que el operador<< toma referencias a nonconst (copiada de operador>>?).y siguen diciendo funciones en std:: son globales).
    • sgi.com/tech/stl para referencia. la diversión. wg21 es open-std.org/jtc1/sc22/wg21 aquí. el último documento de trabajo (c++1x aunque) open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2800.pdf . usted puede encontrar de c++98 borradores también, por supuesto.
    • por supuesto que no estoy solo con lo que yo pienso acerca de cplusplus.com y sitios similares. la gente de ##de c++ canal de irc en freenode me dijo, y yo he visto que están a la derecha a lo largo del tiempo. de todos modos, como digo yo todavía lo utilizan para una referencia rápida. espero que esto ayude un poco 🙂 diviértete

  4. 0

    ¿Por qué estás queriendo hacer esto?

    Usted no puede cambiar el valor de *p, ya que es const std::string. Si usted hizo el cambio, entonces puedes romper las invariantes del contenedor por cambiar el orden de los elementos.

    A menos que tenga otros requisitos que no se han dado aquí, entonces usted debe hacer una copia de la cadena.

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea