Apa cara yang tepat untuk menginisialisasi peta statis? Apakah kita memerlukan fungsi statis yang akan menginisialisasi itu?
447
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:
sumber
extern
variabel tidak akan memiliki nilai yang benar dalam "sebelum konstruk run-time utama" ini jika kompilator hanya melihatextern
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).
Pemakaian:
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.
Pemakaian:
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.Pemakaian:
CATATAN: Sebelumnya saya menggunakan a
operator []
untuk menambahkan nilai aktual. Ini tidak mungkin seperti dikomentari oleh dalle.#################### AKHIR DARI BAGIAN OBSOLETE ####################
sumber
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 ++:
Karena saya menulis jawaban ini C ++ 11 keluar. Anda sekarang dapat langsung menginisialisasi wadah STL menggunakan fitur daftar penginisialisasi baru:
sumber
Sebagai contoh:
Jika peta adalah anggota data kelas, Anda dapat menginisialisasi langsung di header dengan cara berikut (karena C ++ 17):
sumber
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.
sumber
Hanya ingin berbagi C ++ 98 yang murni untuk bekerja:
sumber
Anda dapat mencoba:
sumber
{1, 2}
bukanstd::pair<int, int>(1, 2)
.Ini mirip dengan
PierreBdR
, tanpa menyalin peta.sumber
Jika Anda terjebak dengan C ++ 98 dan tidak ingin menggunakan boost, di sini ada solusi yang saya gunakan ketika saya perlu menginisialisasi peta statis:
sumber
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.
sumber
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.