Yanıtlar:
C ++ 11 kullanma:
#include <map>
using namespace std;
map<int, char> m = {{1, 'a'}, {3, 'b'}, {5, 'c'}, {7, 'd'}};
Kullanılması 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');
En iyi yol bir işlevi kullanmaktır:
#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
bu "ana çalışma zamanı yapıcısından önce" doğru değerlerine sahip olmayacaktır . extern
const map<int,int> m = create_map()
başlatma listesinde bir sınıfın const üyelerini başlatmak için kullanılabileceğine dikkat edin :struct MyClass {const map<int, int> m; MyClass(); }; MyClass::MyClass() : m(create_map())
Arttırmaya benzer bir şey yapmak karmaşık bir mesele değil. Burada, yapıcıyı da dahil etmek için sadece üç işlevi olan bir sınıf var (neredeyse) güçlendirmeyi yaptı.
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;
}
};
Kullanımı:
std :: map mymap = create_map <int, int> (1,2) (3,4) (5,6);
Yukarıdaki kod, bir sınıfın başlatılması gereken global değişkenlerin veya statik üyelerin başlatılması için en iyi sonucu verir ve ilk kez ne zaman kullanıldığına dair hiçbir fikriniz yoktur, ancak değerlerin içinde bulunduğundan emin olmak istersiniz.
Varsa, mevcut bir std :: haritasına eleman eklemeniz gerekir ... işte sizin için başka bir sınıf.
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());
}
};
Kullanımı:
typedef std::map<int, int> Int2IntMap;
Int2IntMap testMap;
map_add_values<Int2IntMap>(1,2)(3,4)(5,6).to(testMap);
GCC 4.7.2 ile çalışırken görün: http://ideone.com/3uYJiH
############### BU AŞAĞIDAKİ HER ŞEY OBSOLET'tir #################
EDIT : map_add_values
Önerdiğim orijinal çözüm olan aşağıdaki sınıf, GCC 4.5+ söz konusu olduğunda başarısız olurdu. Mevcut haritaya nasıl değer ekleyeceğinizi öğrenmek için lütfen yukarıdaki koda bakın .
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;
}
};
Kullanımı:
std :: map <int, int> my_map; // Daha sonra kod boyunca bir yerlerde map_add_values <int, int> (my_map) (1,2) (3,4) (5,6);
NOT: Daha önce operator []
gerçek değerleri eklemek için a kullandım . Bu dalle tarafından yorumlandığı gibi mümkün değildir.
##################### OBSOLETE BÖLÜMÜ SONU ######################
operator[]
sadece tek bir argüman alır.
error: conflicting declaration ‘map_add_values<int, int> my_map’
error: ‘my_map’ has a previous declaration as ‘std::map<int, int> my_map’
İşte 2 öğeli veri yapıcısını kullanan başka bir yol. Başlatılması için herhangi bir işlev gerekmez. Hiçbir 3. parti kodu (Boost), statik işlev veya nesne yok, hile yok, sadece basit C ++:
#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);
Bu cevabı yazdığım için C ++ 11 çıktı. Artık yeni başlatıcı listesi özelliğini kullanarak STL kapsayıcılarını doğrudan başlatabilirsiniz:
const MyMap myMap = { {"hello", 42}, {"world", 88} };
Örneğin:
const std::map<LogLevel, const char*> g_log_levels_dsc =
{
{ LogLevel::Disabled, "[---]" },
{ LogLevel::Info, "[inf]" },
{ LogLevel::Warning, "[wrn]" },
{ LogLevel::Error, "[err]" },
{ LogLevel::Debug, "[dbg]" }
};
Harita bir sınıfın veri üyesiyse, haritayı doğrudan başlıkta şu şekilde başlatabilirsiniz (C ++ 17'den beri):
// 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
};
};
Haritayı statik bir nesnenin içine sarar ve harita başlatma kodunu bu nesnenin yapıcısına koyarım, böylece başlatma kodu yürütülmeden önce haritanın oluşturulduğundan emin olabilirsiniz.
Sadece saf bir C ++ 98 çalışmasını paylaşmak istedim:
#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;
Deneyebilirsin:
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}
bunun yerine daha kısa sözdizimini de kullanabilirsiniz std::pair<int, int>(1, 2)
.
Bu, PierreBdR
haritayı kopyalamadan benzer .
#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);
C ++ 98 ile sıkışmış ve boost kullanmak istemiyorsanız, burada statik bir harita başlatmak gerektiğinde kullandığım çözüm var:
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 ] ) ] );
Burada çok iyi cevaplarınız var, ama bana göre, "bildiğiniz her şey bir çekiç olduğunda" bir durum gibi görünüyor ...
Statik bir haritayı başlatmak için standart bir yolun olmamasının en basit cevabı, statik bir haritayı kullanmak için iyi bir neden yoktur ...
Harita, bilinmeyen bir dizi öğenin hızlı aranması için tasarlanmış bir yapıdır. Önceden öğeleri biliyorsanız, sadece bir C-dizisi kullanın. Değerleri sıralı bir şekilde girin veya bunu yapamıyorsanız sıralama üzerinde çalıştırın. Daha sonra, alt döngülü / üst_bound girişleri artırmak için stl :: fonksiyonlarını kullanarak log (n) performansını elde edebilirsiniz. Bunu daha önce test ettiğimde, normalde bir haritadan en az 4 kat daha hızlı performans gösterirler.
Avantajları çok katlıdır ... - daha hızlı performans (* 4, birçok CPU tipinde ölçtüm, her zaman 4 civarında) - daha basit hata ayıklama. Doğrusal bir düzende neler olduğunu görmek daha kolaydır. - Gerekirse, kopyalama işlemlerinin önemsiz uygulamaları. - Çalışma zamanında bellek ayırmaz, bu yüzden asla bir istisna atmaz. - Bu standart bir arabirimdir ve DLL, veya diller vb. Arasında paylaşmak çok kolaydır.
Devam edebilirdim, ancak daha fazlasını istiyorsanız, neden Stroustrup'un konuyla ilgili birçok bloguna bakmıyorsunuz?
map
aynı zamanda kısmi bir fonksiyonu (matematiksel anlamda fonksiyon; fakat aynı zamanda programlama anlamında) temsil etmek için de yararlı bir formdur. Bir dizi bunu yapmaz. Dize kullanarak bir diziden veri arayamazsınız.