Selalu gunakan varian yang paling menggambarkan apa yang ingin Anda lakukan. Itu adalah
Untuk setiap elemen x
dalam vec
, lakukan bar.process(x)
.
Sekarang, mari kita periksa contoh-contohnya:
std::for_each(vec.begin(), vec.end(),
std::bind1st(std::mem_fun_ref(&Bar::process), bar));
Kami punya di for_each
sana juga - Yippeh . Kami memiliki [begin; end)
rentang yang ingin kami operasikan.
Pada prinsipnya, algoritma itu jauh lebih eksplisit dan dengan demikian lebih disukai daripada implementasi tulisan tangan. Tapi kemudian ... Binder? Memfun? Pada dasarnya C ++ interna tentang cara mendapatkan fungsi anggota? Untuk tugas saya, saya tidak peduli tentang mereka! Saya juga tidak ingin menderita sintaksis verbose yang menyeramkan ini.
Sekarang kemungkinan lainnya:
for (std::vector<Foo>::const_iterator it = vec.begin(); it != vec.end(); ++it)
{
bar.process(*it);
}
Memang, ini adalah pola umum untuk dikenali, tapi ... membuat iterator, looping, incrementing, dereferencing. Ini juga semua hal yang tidak saya pedulikan untuk menyelesaikan tugas saya.
Diakui, terlihat waay lebih baik dari solusi pertama (setidaknya, loop tubuh yang fleksibel dan cukup eksplisit), tapi masih, itu tidak benar-benar yang besar. Kami akan menggunakan ini jika kami tidak memiliki kemungkinan yang lebih baik, tapi mungkin kami ...
Cara yang lebih baik?
Sekarang kembali ke for_each
. Bukankah bagus untuk mengatakan for_each
dan fleksibel dalam operasi yang harus dilakukan juga? Untungnya, sejak C ++ 0x lambdas, kami
for_each(v.begin(), v.end(), [&](const Foo& x) { bar.process(x); })
Sekarang kami telah menemukan solusi abstrak dan generik untuk banyak situasi terkait, perlu dicatat bahwa dalam kasus khusus ini, ada favorit # 1 mutlak :
foreach(const Foo& x, vec) bar.process(x);
Benar-benar tidak bisa lebih jelas dari itu. Untungnya, C ++ 0x mendapatkan ini sintaks mirip built-in !
map(bar.process, vec)
meskipun peta untuk efek samping tidak disarankan dan daftar pemahaman / ekspresi generator direkomendasikan pada peta).