Respostas:
Usando C ++ 11:
#include <map>
using namespace std;
map<int, char> m = {{1, 'a'}, {3, 'b'}, {5, 'c'}, {7, 'd'}};
Usando o 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');
A melhor maneira é usar uma função:
#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();
extern
As variáveis não terão seus valores corretos neste "antes do construtor principal em tempo de execução" se o compilador apenas viu a extern
declaração, mas ainda não executou a definição de variável real .
const map<int,int> m = create_map()
(e, portanto, inicialize os membros const de uma classe na lista de inicialização:struct MyClass {const map<int, int> m; MyClass(); }; MyClass::MyClass() : m(create_map())
Não é uma questão complicada fazer algo semelhante para impulsionar. Aqui está uma classe com apenas três funções, incluindo o construtor, para replicar o que o impulso fez (quase).
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);
O código acima funciona melhor para a inicialização de variáveis globais ou membros estáticos de uma classe que precisa ser inicializada e você não tem idéia de quando é usado primeiro, mas deseja garantir que os valores estejam disponíveis nele.
Se você diz, você precisa inserir elementos em um std :: map existente ... aqui está outra classe para você.
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);
Veja em ação com o GCC 4.7.2 aqui: http://ideone.com/3uYJiH
############### TUDO ABAIXO ESTE É OBSOLETO #################
EDIT : A map_add_values
classe abaixo, que foi a solução original que eu sugeri, falharia quando se trata do GCC 4.5+. Veja o código acima para saber como adicionar valores ao 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> meu_map; // Posteriormente em algum lugar ao longo do código map_add_values <int, int> (meu_map) (1,2) (3,4) (5,6);
NOTA: Anteriormente, usei a operator []
para adicionar os valores reais. Isso não é possível, como comentado por dalle.
##################### FIM DA SEÇÃO OBSOLETA ######################
operator[]
leva apenas um único argumento.
error: conflicting declaration ‘map_add_values<int, int> my_map’
error: ‘my_map’ has a previous declaration as ‘std::map<int, int> my_map’
Aqui está outra maneira que usa o construtor de dados de 2 elementos. Nenhuma função é necessária para inicializá-lo. Não há código de terceiros (Boost), funções ou objetos estáticos, truques, apenas C ++ simples:
#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 escrevi esta resposta, o C ++ 11 está fora. Agora você pode inicializar diretamente os contêineres STL usando o novo recurso de lista de inicializadores:
const MyMap myMap = { {"hello", 42}, {"world", 88} };
Por exemplo:
const std::map<LogLevel, const char*> g_log_levels_dsc =
{
{ LogLevel::Disabled, "[---]" },
{ LogLevel::Info, "[inf]" },
{ LogLevel::Warning, "[wrn]" },
{ LogLevel::Error, "[err]" },
{ LogLevel::Debug, "[dbg]" }
};
Se o mapa for um membro de dados de uma classe, você poderá inicializá-lo diretamente no cabeçalho da seguinte maneira (desde C ++ 17):
// Example
template<>
class StringConverter<CacheMode> final
{
public:
static auto convert(CacheMode mode) -> const std::string&
{
// validate...
return s_modes.at(mode);
}
private:
static inline const std::map<CacheMode, std::string> s_modes =
{
{ CacheMode::All, "All" },
{ CacheMode::Selective, "Selective" },
{ CacheMode::None, "None" }
// etc
};
};
Eu envolvia o mapa dentro de um objeto estático e colocava o código de inicialização do mapa no construtor desse objeto. Dessa forma, você tem certeza de que o mapa é criado antes da execução do código de inicialização.
Só queria compartilhar uma solução 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;
Podes tentar:
std::map <int, int> mymap =
{
std::pair <int, int> (1, 1),
std::pair <int, int> (2, 2),
std::pair <int, int> (2, 2)
};
{1, 2}
vez de std::pair<int, int>(1, 2)
.
É semelhante a PierreBdR
, sem copiar o 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);
Se você está preso ao C ++ 98 e não deseja usar o boost, aqui está a solução que eu uso quando preciso inicializar um 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 ] ) ] );
Você tem algumas respostas muito boas aqui, mas eu sou para mim, parece um caso de "quando tudo que você sabe é um martelo" ...
A resposta mais simples de por que não existe uma maneira padrão de inicializar um mapa estático, não há uma boa razão para usar um mapa estático ...
Um mapa é uma estrutura projetada para pesquisa rápida, de um conjunto desconhecido de elementos. Se você conhece os elementos com antecedência, basta usar uma matriz C. Digite os valores de maneira ordenada ou execute uma classificação neles, se você não puder fazer isso. Você pode obter o desempenho do log (n) usando as funções stl :: para efetuar loop-up de entradas, lower_bound / upper_bound. Quando eu testei isso anteriormente, eles normalmente executam pelo menos 4 vezes mais rápido que um mapa.
As vantagens são muitas vezes ... - desempenho mais rápido (* 4, eu medi em muitos tipos de CPU, é sempre em torno de 4) - depuração mais simples. É mais fácil ver o que está acontecendo com um layout linear. - Implementações triviais de operações de cópia, caso isso seja necessário. - Ele não aloca memória no tempo de execução, portanto, nunca lançará uma exceção. - É uma interface padrão e, portanto, é muito fácil compartilhar entre DLLs ou idiomas, etc.
Eu poderia continuar, mas se você quiser mais, por que não olhar para os muitos blogs da Stroustrup sobre o assunto.
map
também é uma forma útil para representar uma função parcial (função no sentido matemático; mas também, mais ou menos, no sentido de programação). Uma matriz não faz isso. Você não pode, por exemplo, pesquisar dados de uma matriz usando uma string.