Jawaban:
Menggunakan C ++ 11:
#include <map>
using namespace std;
map<int, char> m = {{1, 'a'}, {3, 'b'}, {5, 'c'}, {7, 'd'}};
Menggunakan 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');
Cara terbaik adalah menggunakan fungsi:
#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
variabel tidak akan memiliki nilai yang benar dalam "sebelum konstruk run-time utama" ini jika kompilator hanya melihat extern
deklarasi, tetapi belum mengalami definisi variabel yang sebenarnya .
const map<int,int> m = create_map()
(dan sebagainya, menginisialisasi anggota const dari kelas dalam daftar inisialisasi:struct MyClass {const map<int, int> m; MyClass(); }; MyClass::MyClass() : m(create_map())
Ini bukan masalah rumit untuk membuat sesuatu yang mirip dengan meningkatkan. Inilah kelas dengan hanya tiga fungsi, termasuk konstruktor, untuk mereplikasi apa yang telah dilakukan boost (hampir).
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;
}
};
Pemakaian:
std :: map mymap = create_map <int, int> (1,2) (3,4) (5,6);
Kode di atas berfungsi paling baik untuk inisialisasi variabel global atau anggota statis suatu kelas yang perlu diinisialisasi dan Anda tidak tahu kapan itu digunakan terlebih dahulu tetapi Anda ingin memastikan bahwa nilai-nilai tersedia di dalamnya.
Jika mengatakan, Anda harus memasukkan elemen ke std :: map yang ada ... inilah kelas lain untuk Anda.
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());
}
};
Pemakaian:
typedef std::map<int, int> Int2IntMap;
Int2IntMap testMap;
map_add_values<Int2IntMap>(1,2)(3,4)(5,6).to(testMap);
Lihat beraksi dengan GCC 4.7.2 di sini: http://ideone.com/3uYJiH
############### SEMUA DI BAWAH INI ADALAH OBSOLETE #################
EDIT : map_add_values
Kelas di bawah ini, yang merupakan solusi asli yang saya sarankan, akan gagal ketika datang ke GCC 4.5+. Silakan lihat kode di atas untuk cara menambahkan nilai ke peta yang ada.
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;
}
};
Pemakaian:
std :: map <int, int> my_map; // Kemudian di suatu tempat di sepanjang kode map_add_values <int, int> (my_map) (1,2) (3,4) (5,6);
CATATAN: Sebelumnya saya menggunakan a operator []
untuk menambahkan nilai aktual. Ini tidak mungkin seperti dikomentari oleh dalle.
#################### AKHIR DARI BAGIAN OBSOLETE ####################
operator[]
hanya membutuhkan satu argumen.
error: conflicting declaration ‘map_add_values<int, int> my_map’
error: ‘my_map’ has a previous declaration as ‘std::map<int, int> my_map’
Berikut ini cara lain yang menggunakan konstruktor data 2-elemen. Tidak diperlukan fungsi untuk menginisialisasi itu. Tidak ada kode pihak ke-3 (Boost), tidak ada fungsi atau objek statis, tidak ada trik, cukup sederhana 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);
Karena saya menulis jawaban ini C ++ 11 keluar. Anda sekarang dapat langsung menginisialisasi wadah STL menggunakan fitur daftar penginisialisasi baru:
const MyMap myMap = { {"hello", 42}, {"world", 88} };
Sebagai contoh:
const std::map<LogLevel, const char*> g_log_levels_dsc =
{
{ LogLevel::Disabled, "[---]" },
{ LogLevel::Info, "[inf]" },
{ LogLevel::Warning, "[wrn]" },
{ LogLevel::Error, "[err]" },
{ LogLevel::Debug, "[dbg]" }
};
Jika peta adalah anggota data kelas, Anda dapat menginisialisasi langsung di header dengan cara berikut (karena 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
};
};
Saya akan membungkus peta di dalam objek statis, dan meletakkan kode inisialisasi peta di konstruktor objek ini, dengan cara ini Anda yakin peta dibuat sebelum kode inisialisasi dijalankan.
Hanya ingin berbagi C ++ 98 yang murni untuk bekerja:
#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;
Anda dapat mencoba:
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}
bukan std::pair<int, int>(1, 2)
.
Ini mirip dengan PierreBdR
, tanpa menyalin peta.
#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);
Jika Anda terjebak dengan C ++ 98 dan tidak ingin menggunakan boost, di sini ada solusi yang saya gunakan ketika saya perlu menginisialisasi peta statis:
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 ] ) ] );
Anda memiliki beberapa jawaban yang sangat bagus di sini, tapi bagi saya, sepertinya ini adalah kasus "ketika yang Anda tahu adalah palu" ...
Jawaban paling sederhana mengapa tidak ada cara standar untuk menginisialisasi peta statis, adalah tidak ada alasan yang baik untuk menggunakan peta statis ...
Peta adalah struktur yang dirancang untuk pencarian cepat, dari serangkaian elemen yang tidak diketahui. Jika Anda tahu elemen sebelumnya, cukup gunakan C-array. Masukkan nilai-nilai dengan cara diurutkan, atau jalankan mengurutkannya, jika Anda tidak bisa melakukan ini. Anda kemudian bisa mendapatkan kinerja log (n) dengan menggunakan fungsi stl :: untuk menambahkan entri, lower_bound / upper_bound. Ketika saya telah menguji ini sebelumnya, mereka biasanya melakukan setidaknya 4 kali lebih cepat daripada peta.
Keuntungannya banyak lipat ... - kinerja lebih cepat (* 4, saya sudah mengukur pada banyak jenis CPU, selalu sekitar 4) - debugging sederhana. Hanya lebih mudah untuk melihat apa yang terjadi dengan tata letak linier. - Implementasi sepele dari operasi salinan, jika itu menjadi perlu. - Ini tidak mengalokasikan memori pada saat dijalankan, jadi tidak akan pernah membuang pengecualian. - Ini adalah antarmuka standar, dan sangat mudah untuk dibagikan, DLL, atau bahasa, dll.
Saya bisa melanjutkan, tetapi jika Anda menginginkan lebih, mengapa tidak melihat banyak blog Stroustrup tentang hal ini.
map
juga merupakan bentuk yang berguna untuk mewakili fungsi parsial (fungsi dalam arti matematika; tetapi juga, semacam, dalam pengertian pemrograman). Array tidak melakukan itu. Anda tidak bisa, katakanlah, mencari data dari array menggunakan string.