ejemplo - map c++ insert
Inicializando un std:: map<int, int> en C++ (11)
Aquí hay otra manera que utiliza el constructor de datos de 2 elementos. No se necesitan funciones para inicializarlo. No hay código de terceros (Boost), no hay funciones u objetos estáticos, no hay trucos, solo C ++ simple:
#include <map>
#include <string>
typedef std::map<std::string, int> MyMap;
const MyMap::value_type rawData[] = {
MyMap::value_type("hello", 42),
MyMap::value_type("world", 88),
};
const int numElems = sizeof rawData / sizeof rawData[0];
MyMap myMap(rawData, rawData + numElems);
Desde que escribí esta respuesta C ++ 11 está fuera. Ahora puede inicializar directamente los contenedores STL utilizando la nueva función de lista de inicializador:
const MyMap myMap = { {"hello", 42}, {"world", 88} };
¿Cuál es la forma correcta de inicializar un mapa estático? ¿Necesitamos una función estática que la inicialice?
Esto es similar a PierreBdR
, sin copiar el mapa.
#include <map>
using namespace std;
bool create_map(map<int,int> &m)
{
m[1] = 2;
m[3] = 4;
m[5] = 6;
return true;
}
static map<int,int> m;
static bool _dummy = create_map (m);
La mejor manera es usar una función:
#include <map>
using namespace std;
map<int,int> create_map()
{
map<int,int> m;
m[1] = 2;
m[3] = 4;
m[5] = 6;
return m;
}
map<int,int> m = create_map();
No es un tema complicado hacer algo similar para impulsar. Aquí hay una clase con solo tres funciones, incluido el constructor, para replicar lo que hizo boost (casi).
template <typename T, typename U>
class create_map
{
private:
std::map<T, U> m_map;
public:
create_map(const T& key, const U& val)
{
m_map[key] = val;
}
create_map<T, U>& operator()(const T& key, const U& val)
{
m_map[key] = val;
return *this;
}
operator std::map<T, U>()
{
return m_map;
}
};
Uso:
std::map mymap = create_map<int, int >(1,2)(3,4)(5,6);
El código anterior funciona mejor para la inicialización de variables globales o miembros estáticos de una clase que necesita inicializarse y no tiene idea de cuándo se usa primero, pero quiere asegurarse de que los valores estén disponibles en ella.
Por ejemplo, debes insertar elementos en un std :: map existente ... aquí hay otra clase para ti.
template <typename MapType>
class map_add_values {
private:
MapType mMap;
public:
typedef typename MapType::key_type KeyType;
typedef typename MapType::mapped_type MappedType;
map_add_values(const KeyType& key, const MappedType& val)
{
mMap[key] = val;
}
map_add_values& operator()(const KeyType& key, const MappedType& val) {
mMap[key] = val;
return *this;
}
void to (MapType& map) {
map.insert(mMap.begin(), mMap.end());
}
};
Uso:
typedef std::map<int, int> Int2IntMap;
Int2IntMap testMap;
map_add_values<Int2IntMap>(1,2)(3,4)(5,6).to(testMap);
Véalo en acción con GCC 4.7.2 aquí: http://ideone.com/3uYJiH
############### TODO LO DEBAJO OBSOLETE ##################
EDITAR : La clase map_add_values
continuación, que fue la solución original que sugerí, fallaría cuando se trata de GCC 4.5+. Mire el código anterior para ver cómo agregar valores al mapa existente.
template<typename T, typename U>
class map_add_values
{
private:
std::map<T,U>& m_map;
public:
map_add_values(std::map<T, U>& _map):m_map(_map){}
map_add_values& operator()(const T& _key, const U& _val)
{
m_map[key] = val;
return *this;
}
};
Uso:
std::map<int, int> my_map; // Later somewhere along the code map_add_values<int,int>(my_map)(1,2)(3,4)(5,6);
NOTA: Anteriormente usé un operator []
para agregar los valores reales. Esto no es posible según lo comentado por dalle.
##################### FIN DE LA SECCIÓN OBSOLETA ######################
Por ejemplo:
const std::map<LoggerLevel, const char*> g_logLevelsDescriptions =
{
{ LoggerLevel::llNothing, "Logging disabled" },
{ LoggerLevel::llInfo, "Base information" },
{ LoggerLevel::llWarn, "Warnings" },
{ LoggerLevel::llError, "Errors" },
{ LoggerLevel::llDebug, "All information: debug-mode" }
};
Puedes probar:
std::map <int, int> mymap =
{
std::pair <int, int> (1, 1),
std::pair <int, int> (2, 2),
std::pair <int, int> (2, 2)
};
Si estás atascado con C ++ 98 y no quieres usar boost, aquí está la solución que uso cuando necesito inicializar un mapa estático:
typedef std::pair< int, char > elemPair_t;
elemPair_t elemPairs[] =
{
elemPair_t( 1, ''a''),
elemPair_t( 3, ''b'' ),
elemPair_t( 5, ''c'' ),
elemPair_t( 7, ''d'' )
};
const std::map< int, char > myMap( &elemPairs[ 0 ], &elemPairs[ sizeof( elemPairs ) / sizeof( elemPairs[ 0 ] ) ] );
Solo quería compartir una solución de C ++ 98 pura:
#include <map>
std::map<std::string, std::string> aka;
struct akaInit
{
akaInit()
{
aka[ "George" ] = "John";
aka[ "Joe" ] = "Al";
aka[ "Phil" ] = "Sue";
aka[ "Smitty" ] = "Yando";
}
} AkaInit;
Tiene algunas respuestas muy buenas aquí, pero yo soy para mí, parece un caso de "cuando todo lo que sabe es un martillo" ...
La respuesta más simple a por qué no hay una manera estándar de inicializar un mapa estático, es que no hay una buena razón para usar un mapa estático ...
Un mapa es una estructura diseñada para una búsqueda rápida, de un conjunto de elementos desconocido. Si conoce los elementos de antemano, simplemente use un C-array. Ingrese los valores ordenados, o ejecute la ordenación en ellos, si no puede hacer esto. Luego puede obtener el rendimiento de log (n) utilizando las funciones stl :: para enrollar entradas, lower_bound / upper_bound. Cuando he probado esto anteriormente, normalmente funcionan al menos 4 veces más rápido que un mapa.
Las ventajas son muchas más ... - rendimiento más rápido (* 4, he medido en muchos tipos de CPU, siempre es alrededor de 4) - depuración más simple. Es más fácil ver lo que está pasando con un diseño lineal. - Implementaciones triviales de operaciones de copia, en caso de que sean necesarias. - No asigna memoria en tiempo de ejecución, por lo que nunca lanzará una excepción. - Es una interfaz estándar, por lo que es muy fácil de compartir, DLL, o idiomas, etc.
Podría seguir, pero si quiere más, ¿por qué no mirar los muchos blogs de Stroustrup sobre el tema?
Usando C ++ 11:
#include <map>
using namespace std;
map<int, char> m = {{1, ''a''}, {3, ''b''}, {5, ''c''}, {7, ''d''}};
Utilizando Boost.Assign :
#include <map>
#include "boost/assign.hpp"
using namespace std;
using namespace boost::assign;
map<int, char> m = map_list_of (1, ''a'') (3, ''b'') (5, ''c'') (7, ''d'');
Yo envolvería el mapa dentro de un objeto estático y pondría el código de inicialización del mapa en el constructor de este objeto, de esta manera está seguro de que el mapa se crea antes de que se ejecute el código de inicialización.