Contoh yang dibuat-buat, demi pertanyaan:
void MyClass::MyFunction( int x ) const
{
std::cout << m_map[x] << std::endl
}
Ini tidak akan bisa dikompilasi, karena operator [] adalah non-const.
Ini sangat disayangkan, karena sintaks [] terlihat sangat bersih. Sebaliknya, saya harus melakukan sesuatu seperti ini:
void MyClass::MyFunction( int x ) const
{
MyMap iter = m_map.find(x);
std::cout << iter->second << std::endl
}
Ini selalu mengganggu saya. Mengapa operator [] bukan konstanta?
operator[]
dihasilkan jika elemen yang diberikan tidak ada?Jawaban:
Untuk
std::map
danstd::unordered_map
,operator[]
akan memasukkan nilai indeks ke dalam wadah jika sebelumnya tidak ada. Ini sedikit tidak intuitif, tapi begitulah adanya.Karena harus dibiarkan gagal dan memasukkan nilai default, operator tidak dapat digunakan pada
const
instance penampung.http://en.cppreference.com/w/cpp/container/map/operator_at
sumber
std::set
tidak punyaoperator[]
.std::vector
memiliki operator membaca[]
yangconst
.map
harus melakukan hal yang sama.Sekarang dengan C ++ 11 Anda dapat memiliki versi yang lebih bersih dengan menggunakan at ()
void MyClass::MyFunction( int x ) const { std::cout << m_map.at(x) << std::endl; }
sumber
map
memiliki const dan non-constat()
s - mengapa tidak sama juga untukoperator[]
? dengan versi const tidak memasukkan apa-apa melainkan melempar? (Atau mengembalikan opsional, ketika std :: opsional menjadikannya standar)at
datang dalam dua ragam adalah karena ia melakukan areturn *this;
, dan satu-satunya perbedaan antara kelebihan beban adalahconst
-ness dari referensi yang dikembalikan. Efek sebenarnya dari keduanyaat
sama persis (yaitu, tidak ada efek).Catatan untuk pembaca baru.
Pertanyaan asli adalah tentang kontainer STL (tidak secara khusus tentang std :: map)
Perlu dicatat bahwa ada versi const dari operator [] di sebagian besar penampung.
Hanya saja std :: map dan std :: set tidak memiliki versi const dan ini adalah hasil dari struktur dasar yang mengimplementasikannya.
Dari std :: vector
reference operator[](size_type n) const_reference operator[](size_type n) const
Juga untuk contoh kedua Anda, Anda harus memeriksa kegagalan untuk menemukan elemen tersebut.
void MyClass::MyFunction( int x ) const { MyMap iter = m_map.find(x); if (iter != m_map.end()) { std::cout << iter->second << std::endl } }
sumber
std::set
tidak punyaoperator[]
sama sekali.Karena operator [] mungkin memasukkan elemen baru ke dalam wadah, itu tidak mungkin menjadi fungsi anggota const. Perhatikan bahwa definisi operator [] sangat sederhana: m [k] setara dengan (* ((m.insert (value_type (k, data_type ()))). First)). Second. Sebenarnya, fungsi anggota ini tidak diperlukan: ini hanya ada untuk kenyamanan
sumber
Operator indeks seharusnya hanya menjadi const untuk penampung hanya-baca (yang sebenarnya tidak ada di STL).
Operator indeks tidak hanya digunakan untuk melihat nilai.
sumber
const
, yang lain bukanconst
- sepertistd::vector
halnya.Jika Anda mendeklarasikan variabel std :: map member Anda menjadi bisa berubah
mutable std::map<...> m_map;
Anda dapat menggunakan fungsi anggota non-const dari std :: map dalam fungsi anggota const Anda.
sumber
mutable
dapat digunakan untuk anggota sepertistd::mutex
, cache dan pembantu debug. Jika peta akan digunakan sebagai cache untuk mempercepatconst
fungsi "pengambil" yang sangat mahal , makamutable
itu dapat diterima. Anda perlu berhati-hati, tetapi itu sendiri bukanlah ide yang buruk.