Forma recomendada de insertar elementos en el mapa [duplicar]


Posible Duplicado:
En los mapas STL, ¿es mejor usar map:: insert que []?

Me preguntaba, cuando inserto un elemento en el mapa, cuál es la forma recomendada. Debería

map[key] = value;

O

map.insert(std::pair<key_type, value_type>(key, value));

Hice la siguiente prueba rápida:

#include <map>
#include <string>
#include <iostream>

class Food {
public:
    Food(const std::string& name) : name(name) { std::cout << "constructor with string parameter" << std::endl; }
    Food(const Food& f) : name(f.name) { std::cout << "copy" << std::endl; }
    Food& operator=(const Food& f) { name = f.name; std::cout << "=" << std::endl; return *this; } 
    Food() { std::cout << "default" << std::endl; }
    std::string name;
};

int main() {
    std::map<std::string, Food> m0;

/*
1) constructor with string parameter
2) copy
3) copy
4) copy
*/
    m0.insert(std::pair<std::string, Food>("Key", Food("Ice Cream")));

/*
1) constructor with string parameter
2) default
3) copy
4) copy
5) =
*/
    // If we do not provide default constructor.
    // C2512: 'Food::Food' : no appropriate default constructor available
    m0["Key"] = Food("Ice Cream");
}
  1. Me doy cuenta de que usando la función miembro insert, la llamada a la función de menos valor estará involucrada. Entonces, ¿usar insert es una forma recomendada?
  2. Por qué el constructor predeterminado es necesario, cuando map[key] = value camino se está utilizando?

Sé que insert no sobrescribe el par de valores de clave de existencia, pero map[key] = value lo hace. Sin embargo, es este el único factor que tengo en cuenta, cuando tratar de elegir entre los dos?

¿Qué tal

  1. Rendimiento
  2. Disponibilidad del constructor predeterminado de value
  3. ???
Author: Community, 2011-08-05

4 answers

  1. insert no es una forma recomendada - es una de las formas de insertar en el mapa. La diferencia con operator[] es que el insert puede decir si el elemento está insertado en el mapa. Además, si su clase no tiene un constructor predeterminado, se verá obligado a usar insert.
  2. operator[] necesita el constructor predeterminado porque el mapa comprueba si el elemento existe. Si no lo hace, entonces crea uno usando el constructor predeterminado y devuelve una referencia (o referencia const a se).

Debido a que los contenedores map no permiten valores de clave duplicados, la operación de inserción comprueba para cada elemento insertado si ya existe otro elemento en el contenedor con el mismo valor de clave, si es así, el elemento no se inserta y su valor asignado no se cambia de ninguna manera.

 49
Author: BЈовић,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-11 13:58:07

Use insert si desea insertar un nuevo elemento. insert no sobrescribir un elemento existente, y se puede verificar que no hubo elemento anterior:

if ( !myMap.insert( std::make_pair( key, value ) ).second ) {
    //  Element already present...
}

Use [] si desea sobrescribir un elemento posiblemente existente:

myMap[ key ] = value;
assert( myMap.find( key )->second == value ); // post-condition

Este formulario sobrescribirá cualquier entrada existente.

 38
Author: James Kanze,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-05 08:57:25

Para citar:

Debido a que los contenedores map no permiten valores de clave duplicados, la operación de inserción comprueba para cada elemento insertado si ya existe otro elemento en el contenedor con el mismo valor de clave, si es así, el elemento no se inserta y su valor asignado no se cambia de ninguna manera.

Así que insert no cambiará el valor si la clave ya existe, el [] operator lo hará.

EDITAR:

Esto me recuerda a otra pregunta reciente-por qué usar at() en lugar de [] operator para recuperar valores de un vector. Aparentemente at() lanza una excepción si el índice está fuera de los límites mientras que [] operator no. En estas situaciones siempre es mejor buscar la documentación de las funciones, ya que le darán todos los detalles. Pero en general, no hay (o al menos no debería haber) dos funciones / operadores que hagan exactamente lo mismo.

Mi conjetura es que, internamente, insert() primero comprobará la entrada y luego utilizará el [] operator.

 13
Author: Luchian Grigore,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-15 18:20:33

map[key] = value se proporciona para facilitar la sintaxis. Es más fácil leer y escribir.

La razón por la que necesita tener un constructor predeterminado es que map[key] se evalúa antes de la asignación. Si la clave no estaba presente en el mapa, se crea una nueva (con el constructor predeterminado) y la referencia a ella se devuelve desde operator[].

 10
Author: x13n,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-05 06:55:17