Apa cara terbaik untuk menentukan apakah peta STL berisi nilai untuk kunci yang diberikan?
#include <map>
using namespace std;
struct Bar
{
int i;
};
int main()
{
map<int, Bar> m;
Bar b = {0};
Bar b1 = {1};
m[0] = b;
m[1] = b1;
//Bar b2 = m[2];
map<int, Bar>::iterator iter = m.find(2);
Bar b3 = iter->second;
}
Memeriksa ini dalam debugger, sepertinya iter
hanya data sampah.
Jika saya batalkan komentar pada baris ini:
Bar b2 = m[2]
Debugger menunjukkan bahwa b2
adalah {i = 0}
. (Saya menduga itu berarti bahwa menggunakan indeks yang tidak ditentukan akan mengembalikan struct dengan semua nilai kosong / tidak diinisialisasi?)
Tidak satu pun dari metode ini yang begitu hebat. Yang benar-benar saya suka adalah antarmuka seperti ini:
bool getValue(int key, Bar& out)
{
if (map contains value for key)
{
out = map[key];
return true;
}
return false;
}
Apakah ada sesuatu di sepanjang garis ini ada?
Jawaban:
Tidak. Dengan kelas peta stl, Anda menggunakan
::find()
untuk mencari peta, dan membandingkan iterator yang dikembalikanstd::map::end()
begitu
Jelas Anda dapat menulis
getValue()
rutin sendiri jika Anda mau (juga di C ++, tidak ada alasan untuk menggunakanout
), tetapi saya akan curiga bahwa begitu Anda terbiasa menggunakanstd::map::find()
Anda tidak akan mau membuang waktu Anda.Juga kode Anda sedikit salah:
m.find('2');
akan mencari peta untuk nilai kunci itu'2'
. IIRC, kompiler C ++ secara implisit akan mengkonversi '2' ke int, yang menghasilkan nilai numerik untuk kode ASCII untuk '2' yang bukan yang Anda inginkan.Karena jenis kunci Anda dalam contoh ini adalah
int
Anda ingin mencari seperti ini:m.find(2);
sumber
find
menunjukkan niat jauh lebih baik daripadacount
melakukannya. Terlebih lagi,count
tidak mengembalikan item. Jika Anda membaca pertanyaan OP, dia ingin memeriksa keberadaannya, dan mengembalikan elemen tersebut.find
apakah itu.count
tidak.Selama peta bukan multimap, salah satu cara paling elegan adalah dengan menggunakan metode penghitungan
Hitungannya akan menjadi 1 jika elemen tersebut memang ada di peta.
sumber
operator[]
).find
memberi AndaTryGetValue
semantik NET. , yang hampir selalu apa yang Anda (dan khususnya OP) inginkan.Itu sudah ada dengan find saja tidak dalam sintaks yang tepat.
Jika Anda ingin mengakses nilai jika ada, Anda dapat melakukan:
Dengan C ++ 0x dan otomatis, sintaksinya lebih sederhana:
Saya sarankan Anda terbiasa daripada mencoba untuk membuat mekanisme baru untuk menyederhanakannya. Anda mungkin dapat mengurangi sedikit kode, tetapi pertimbangkan biaya untuk melakukan itu. Sekarang Anda telah memperkenalkan fungsi baru yang tidak dapat dikenali oleh orang yang akrab dengan C ++.
Jika Anda tetap ingin menerapkan ini terlepas dari peringatan ini, maka:
sumber
Saya hanya memperhatikan bahwa dengan C ++ 20 , kita akan memilikinya
Itu akan kembali benar jika peta memegang elemen dengan kunci
key
.sumber
amap.find
kembaliamap::end
ketika tidak menemukan apa yang Anda cari - Anda seharusnya memeriksanya.sumber
Periksa nilai balik
find
terhadapend
.sumber
Anda dapat membuat fungsi getValue Anda dengan kode berikut:
sumber
out = foundIter->second
out = foundIter->second
daripadaout = *foundIter
Untuk meringkas beberapa jawaban lain dengan ringkas:
Jika Anda belum menggunakan C ++ 20, Anda dapat menulis
mapContainsKey
fungsi Anda sendiri :Jika Anda ingin menghindari banyak kelebihan
map
vsunordered_map
dan jenis kunci dan nilai yang berbeda, Anda bisa menjadikannyatemplate
fungsi.Jika Anda menggunakan
C++ 20
atau lebih baru, akan adacontains
fungsi bawaan:sumber
Jika Anda ingin menentukan apakah kunci ada di peta atau tidak, Anda dapat menggunakan fungsi find () atau count () anggota. Fungsi find yang digunakan di sini sebagai contoh mengembalikan iterator ke elemen atau map :: end sebaliknya. Dalam hal penghitungan, penghitungan pengembalian 1 jika ditemukan, jika tidak maka akan mengembalikan nol (atau sebaliknya).
sumber
Boost multindex dapat digunakan untuk solusi yang tepat. Solusi berikut bukanlah pilihan terbaik tetapi mungkin berguna dalam beberapa kasus di mana pengguna menetapkan nilai default seperti 0 atau NULL pada inisialisasi dan ingin memeriksa apakah nilainya telah dimodifikasi.
sumber