Kode berikut mengatakan bahwa meneruskan peta const
ke dalam operator[]
metode membuang qualifier:
#include <iostream>
#include <map>
#include <string>
using namespace std;
class MapWrapper {
public:
const int &get_value(const int &key) const {
return _map[key];
}
private:
map<int, int> _map;
};
int main() {
MapWrapper mw;
cout << mw.get_value(42) << endl;
return 0;
}
Apakah ini karena kemungkinan alokasi yang terjadi pada akses peta? Apakah tidak ada fungsi dengan akses peta yang dideklarasikan sebagai const?
MapWrapper.cpp:10: error: passing ‘const std::map<int, int, std::less<int>, std::allocator<std::pair<const int, int> > >’ as ‘this’ argument of ‘_Tp& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&) [with _Key = int, _Tp = int, _Compare = std::less<int>, _Alloc = std::allocator<std::pair<const int, int> >]’ discards qualifiers
Jawaban:
std::map
'soperator []
tidak dideklarasikan sebagaiconst
, dan tidak bisa karena perilakunya:Akibatnya, fungsi Anda tidak dapat dideklarasikan
const
, dan menggunakan petaoperator[]
.std::map
'sfind()
fungsi memungkinkan Anda untuk mencari kunci tanpa memodifikasi peta.find()
mengembalikaniterator
, atauconst_iterator
ke yangstd::pair
berisi kunci (.first
) dan nilai (.second
).Di C ++ 11, Anda juga bisa menggunakan
at()
untukstd::map
. Jika elemen tidak ada, fungsi melontarkanstd::out_of_range
pengecualian, berbeda denganoperator []
.sumber
operator[]
(egfoo[bar] = baz
) dan rvalueoperator[]
(egx = foo[bar]
) - yang terakhir pasti bisa menjadi const.Karena
operator[]
tidak memiliki kelebihan beban berkualifikasi const, kelebihan beban tidak dapat digunakan dengan aman dalam fungsi berkualifikasi const. Ini mungkin karena kelebihan beban saat ini dibuat dengan tujuan mengembalikan dan menetapkan nilai kunci.Sebagai gantinya, Anda dapat menggunakan:
atau, di C ++ 11, Anda dapat menggunakan
at()
operator:sumber
map.find(KEY)->second;
tidak aman jika nilai peta adalah string. Ini cenderung mencetak sampah jika KUNCI tidak ditemukan.Anda tidak dapat menggunakan
operator[]
pada petaconst
karena metode itu tidakconst
memungkinkan Anda untuk memodifikasi peta (Anda dapat menetapkannya_map[key]
). Coba gunakanfind
metode ini sebagai gantinya.sumber
Beberapa versi terbaru dari header GCC (4.1 dan 4.2 pada mesin saya) memiliki fungsi anggota non-standar map :: at () yang dideklarasikan const dan membuang std :: out_of_range jika kuncinya tidak ada di peta.
Dari referensi di komentar fungsi, tampaknya ini telah disarankan sebagai fungsi anggota baru di pustaka standar.
sumber
Pertama, Anda tidak boleh menggunakan simbol yang diawali dengan _ karena simbol tersebut disediakan untuk implementasi bahasa / penulis kompilator. Akan sangat mudah bagi _map untuk menjadi kesalahan sintaks pada kompilator seseorang, dan Anda tidak akan menyalahkan siapa pun kecuali diri Anda sendiri.
Jika Anda ingin menggunakan garis bawah, letakkan di akhir, bukan di awal. Anda mungkin melakukan kesalahan ini karena Anda melihat beberapa kode Microsoft melakukannya. Ingat, mereka menulis kompiler mereka sendiri, jadi mereka mungkin bisa lolos begitu saja. Meski begitu, itu ide yang buruk.
operator [] tidak hanya mengembalikan referensi, tetapi juga membuat entri di peta. Jadi, Anda tidak hanya mendapatkan pemetaan, jika tidak ada, Anda membuatnya. Bukan itu yang Anda inginkan.
sumber
_
salah. Pengenal yang dimulai dengan dua garis bawah (__example
) atau pengenal yang dimulai dengan satu garis bawah dan huruf kapital (_Example
) dicadangkan._example
tidak dicadangkan.