Apakah ada kelebihan std::for_each
over for
loop? Bagi saya, std::for_each
sepertinya hanya menghambat pembacaan kode. Mengapa beberapa standar pengkodean merekomendasikan penggunaannya?
Apakah ada kelebihan std::for_each
over for
loop? Bagi saya, std::for_each
sepertinya hanya menghambat pembacaan kode. Mengapa beberapa standar pengkodean merekomendasikan penggunaannya?
Jawaban:
Yang menyenangkan dengan C ++ 11 (sebelumnya disebut C ++ 0x), adalah bahwa perdebatan yang melelahkan ini akan diselesaikan.
Maksudku, tidak ada yang waras, yang ingin mengulang seluruh koleksi, masih akan menggunakan ini
for(auto it = collection.begin(); it != collection.end() ; ++it)
{
foo(*it);
}
Atau ini
for_each(collection.begin(), collection.end(), [](Element& e)
{
foo(e);
});
ketika sintaks loop berbasis rentangfor
tersedia:
for(Element& e : collection)
{
foo(e);
}
Sintaks semacam ini telah tersedia di Java dan C # untuk beberapa waktu sekarang, dan sebenarnya ada lebih banyak foreach
loop daripada for
loop klasik di setiap kode Java atau C # yang saya lihat baru-baru ini.
Element & e
sebagai auto & e
(atau auto const &e
) terlihat lebih baik. Saya akan menggunakan Element const e
(tanpa referensi) ketika saya ingin konversi implisit, katakan ketika sumbernya adalah kumpulan dari berbagai jenis, dan saya ingin mereka mengubahnya menjadi Element
.
Berikut beberapa alasannya:
Tampaknya menghambat keterbacaan hanya karena Anda tidak terbiasa dan / atau tidak menggunakan alat yang tepat di sekitarnya untuk membuatnya sangat mudah. (lihat boost :: range dan boost :: bind / boost :: lambda untuk helpers. Banyak di antaranya akan masuk ke C ++ 0x dan membuat for_each dan fungsi terkait lebih bermanfaat.)
Hal ini memungkinkan Anda untuk menulis algoritma di atas for_each yang bekerja dengan iterator apa pun.
Ini mengurangi kemungkinan bug pengetikan yang bodoh.
Hal ini juga membuka pikiran Anda untuk sisa STL-algoritma, seperti find_if
, sort
, replace
, dll dan ini tidak akan terlihat begitu aneh lagi. Ini bisa menjadi kemenangan besar.
Pembaruan 1:
Yang paling penting, ini membantu Anda melampaui for_each
vs untuk-loop seperti itu semua yang ada, dan melihat STL-alogs lainnya, seperti menemukan / sort / partisi / copy_replace_if, eksekusi paralel .. atau apa pun.
Banyak pemrosesan dapat ditulis dengan sangat ringkas menggunakan "sisa" saudara for_each, tetapi jika semua yang Anda lakukan adalah menulis for-loop dengan berbagai logika internal, maka Anda tidak akan pernah belajar cara menggunakannya, dan Anda akan akhirnya menciptakan roda berulang-ulang.
Dan (for_each gaya rentang yang akan segera tersedia):
for_each(monsters, boost::mem_fn(&Monster::think));
Atau dengan C ++ x11 lambdas:
for_each(monsters, [](Monster& m) { m.think(); });
apakah IMO lebih mudah dibaca daripada:
for(Monsters::iterator i = monsters.begin(); i != monsters.end(); ++i) {
i->think();
}
Juga ini (atau dengan lambdas, lihat yang lain):
for_each(bananas, boost::bind(&Monkey::eat, my_monkey, _1));
Lebih ringkas daripada:
for(Bananas::iterator i = bananas.begin(); i != bananas.end(); ++i) {
my_monkey->eat(*i);
}
Terutama jika Anda memiliki beberapa fungsi untuk dipanggil ... tapi mungkin itu hanya saya. ;)
Pembaruan 2 : Saya telah menulis pembungkus satu-liner saya sendiri dari stl-algos yang bekerja dengan rentang alih-alih sepasang iterator. boost :: range_ex, setelah dirilis, akan memasukkan itu dan mungkin itu akan ada di C ++ 0x juga?
outer_class::inner_class::iterator
atau mereka adalah argumen templat: typename std::vector<T>::iterator
... untuk konstruk itu sendiri dapat berjalan ke banyak garis konstruksinya sendiri
for_each
contoh kedua tidak benar (seharusnyafor_each( bananas.begin(), bananas.end(),...
for_each
lebih generik. Anda dapat menggunakannya untuk beralih ke semua jenis wadah (dengan melewati iterator begin / end). Anda dapat berpotensi menukar wadah di bawah fungsi yang digunakan for_each
tanpa harus memperbarui kode iterasi. Anda perlu mempertimbangkan bahwa ada wadah lain di dunia selain std::vector
dan array C lama untuk melihat manfaatnya for_each
.
Kelemahan utama dari for_each
ini adalah dibutuhkan functor, sehingga sintaksnya kikuk. Ini diperbaiki dalam C ++ 11 (sebelumnya C ++ 0x) dengan pengenalan lambdas:
std::vector<int> container;
...
std::for_each(container.begin(), container.end(), [](int& i){
i+= 10;
});
Ini tidak akan terlihat aneh bagi Anda dalam 3 tahun.
for ( int v : int_vector ) {
(bahkan jika itu dapat disimulasikan hari ini dengan BOOST_FOREACH)
std::for_each(container, [](int& i){ ... });
. Maksud saya mengapa seseorang dipaksa untuk menulis wadah dua kali?
container.each { ... }
tanpa menyebutkan awal dan akhir iterator. Saya merasa sedikit berlebihan bahwa saya harus menentukan iterator akhir sepanjang waktu.
Secara pribadi, setiap kali saya harus keluar dari cara saya untuk menggunakan std::for_each
(menulis fungsi tujuan khusus / rumit boost::lambda
), saya menemukan BOOST_FOREACH
dan berbasis C ++ 0x untuk lebih jelas:
BOOST_FOREACH(Monster* m, monsters) {
if (m->has_plan())
m->act();
}
vs.
std::for_each(monsters.begin(), monsters.end(),
if_then(bind(&Monster::has_plan, _1),
bind(&Monster::act, _1)));
sangat subyektif, beberapa orang akan mengatakan bahwa menggunakan for_each
akan membuat kode lebih mudah dibaca, karena memungkinkan untuk memperlakukan koleksi yang berbeda dengan konvensi yang sama.
for_each
itslef diimplementasikan sebagai loop
template<class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function f)
{
for ( ; first!=last; ++first ) f(*first);
return f;
}
jadi terserah kepada Anda untuk memilih apa yang tepat untuk Anda.
Seperti banyak fungsi algoritma, reaksi awal adalah berpikir bahwa lebih sulit untuk menggunakan foreach daripada loop. Sudah menjadi topik banyak perang api.
Setelah Anda terbiasa dengan idiom Anda mungkin merasa berguna. Satu keuntungan yang jelas adalah bahwa hal itu memaksa pembuat kode untuk memisahkan isi dalam loop dari fungsi iterasi yang sebenarnya. (OK, saya pikir ini keuntungan. Lainnya mengatakan Anda hanya memotong kode tanpa manfaat nyata).
Satu keuntungan lainnya adalah ketika saya melihat foreach, saya tahu bahwa setiap item akan diproses atau pengecualian akan dilemparkan.
A for loop memungkinkan beberapa opsi untuk mengakhiri loop. Anda dapat membiarkan loop menjalankan program penuhnya, atau Anda dapat menggunakan kata kunci break untuk secara eksplisit melompat keluar dari loop, atau menggunakan kata kunci kembali untuk keluar dari seluruh fungsi mid-loop. Sebaliknya, foreach tidak mengizinkan opsi ini, dan ini membuatnya lebih mudah dibaca. Anda bisa melihat sekilas pada nama fungsi dan Anda tahu sifat penuh iterasi.
Berikut ini adalah contoh dari membingungkan untuk lingkaran:
for(std::vector<widget>::iterator i = v.begin(); i != v.end(); ++i)
{
/////////////////////////////////////////////////////////////////////
// Imagine a page of code here by programmers who don't refactor
///////////////////////////////////////////////////////////////////////
if(widget->Cost < calculatedAmountSofar)
{
break;
}
////////////////////////////////////////////////////////////////////////
// And then some more code added by a stressed out juniour developer
// *#&$*)#$&#(#)$#(*$&#(&*^$#(*$#)($*#(&$^#($*&#)$(#&*$&#*$#*)$(#*
/////////////////////////////////////////////////////////////////////////
for(std::vector<widgetPart>::iterator ip = widget.GetParts().begin(); ip != widget.GetParts().end(); ++ip)
{
if(ip->IsBroken())
{
return false;
}
}
}
std::for_each()
dalam standar lama (pada saat posting ini) Anda harus menggunakan functor bernama, yang mendorong keterbacaan seperti yang Anda katakan dan melarang keluar dari loop sebelum waktunya. Tapi kemudian for
loop ekivalen tidak memiliki apa-apa selain panggilan fungsi, dan itu juga melarang keluar sebelum waktunya. Tapi selain itu saya pikir Anda membuat poin yang sangat baik dalam mengatakan bahwa std::for_each()
memaksa melalui seluruh jajaran.
Anda sebagian besar benar: sebagian besar waktu, std::for_each
adalah kerugian bersih. Aku akan pergi sejauh untuk membandingkan for_each
ke goto
. goto
memberikan kontrol aliran paling fleksibel yang memungkinkan - Anda dapat menggunakannya untuk mengimplementasikan hampir semua struktur kontrol lain yang dapat Anda bayangkan. Namun, keserbagunaan itu berarti bahwa melihat secara goto
terpisah tidak memberi tahu Anda apa pun yang dimaksudkan untuk dilakukan dalam situasi ini. Akibatnya, hampir tidak ada orang waras yang menggunakan goto
kecuali sebagai pilihan terakhir.
Di antara algoritma standar, cara for_each
yang hampir sama - dapat digunakan untuk mengimplementasikan apa saja, yang berarti bahwa melihat for_each
hampir tidak memberi tahu Anda tentang apa yang digunakan untuk situasi ini. Sayangnya, sikap orang terhadap for_each
adalah tentang di mana sikap mereka terhadap goto
(katakanlah) tahun 1970 atau lebih - beberapa orang telah menangkap fakta bahwa itu harus digunakan hanya sebagai jalan terakhir, tetapi banyak yang masih menganggapnya sebagai algoritma utama, dan jarang jika pernah menggunakan yang lain. Sebagian besar waktu, bahkan pandangan sekilas akan mengungkapkan bahwa salah satu alternatif secara drastis lebih unggul.
Sebagai contoh, saya cukup yakin saya telah kehilangan jejak berapa kali saya melihat orang menulis kode untuk mencetak konten koleksi menggunakan for_each
. Berdasarkan posting yang saya lihat, ini mungkin satu-satunya penggunaan yang paling umum for_each
. Mereka berakhir dengan sesuatu seperti:
class XXX {
// ...
public:
std::ostream &print(std::ostream &os) { return os << "my data\n"; }
};
Dan pasca mereka bertanya tentang apa kombinasi bind1st
, mem_fun
, dll mereka perlu untuk membuat sesuatu seperti:
std::vector<XXX> coll;
std::for_each(coll.begin(), coll.end(), XXX::print);
bekerja, dan cetak elemen coll
. Jika itu benar-benar bekerja persis seperti yang saya tulis di sana, itu akan biasa-biasa saja, tetapi tidak - dan pada saat Anda sudah membuatnya berfungsi, sulit untuk menemukan beberapa bit kode yang terkait dengan apa terjadi di antara potongan-potongan yang menyatukannya.
Untungnya, ada cara yang jauh lebih baik. Tambahkan kelebihan inserter aliran normal untuk XXX:
std::ostream &operator<<(std::ostream *os, XXX const &x) {
return x.print(os);
}
dan gunakan std::copy
:
std::copy(coll.begin(), coll.end(), std::ostream_iterator<XXX>(std::cout, "\n"));
Itu bekerja - dan hampir tidak ada pekerjaan sama sekali untuk mengetahui bahwa ia mencetak konten coll
untuk std::cout
.
boost::mem_fn(&XXX::print)
bukanXXX::print
std::cout
sebagai argumennya agar itu berfungsi).
Keuntungan menulis fungsional agar lebih mudah dibaca, mungkin tidak muncul kapan for(...)
dan for_each(...
).
Jika Anda menggunakan semua algoritma di functional.h, alih-alih menggunakan for-loop, kode menjadi jauh lebih mudah dibaca;
iterator longest_tree = std::max_element(forest.begin(), forest.end(), ...);
iterator first_leaf_tree = std::find_if(forest.begin(), forest.end(), ...);
std::transform(forest.begin(), forest.end(), firewood.begin(), ...);
std::for_each(forest.begin(), forest.end(), make_plywood);
adalah jauh lebih mudah dibaca daripada;
Forest::iterator longest_tree = it.begin();
for (Forest::const_iterator it = forest.begin(); it != forest.end(); ++it{
if (*it > *longest_tree) {
longest_tree = it;
}
}
Forest::iterator leaf_tree = it.begin();
for (Forest::const_iterator it = forest.begin(); it != forest.end(); ++it{
if (it->type() == LEAF_TREE) {
leaf_tree = it;
break;
}
}
for (Forest::const_iterator it = forest.begin(), jt = firewood.begin();
it != forest.end();
it++, jt++) {
*jt = boost::transformtowood(*it);
}
for (Forest::const_iterator it = forest.begin(); it != forest.end(); ++it{
std::makeplywood(*it);
}
Dan itulah yang menurut saya sangat bagus, menggeneralisasi for-loop ke fungsi satu baris =)
Mudah: for_each
berguna ketika Anda sudah memiliki fungsi untuk menangani setiap item array, jadi Anda tidak perlu menulis lambda. Tentu saja ini
for_each(a.begin(), a.end(), a_item_handler);
lebih baik dari
for(auto& item: a) {
a_item_handler(a);
}
Juga, for
loop berkisar hanya beralih di seluruh wadah dari awal sampai akhir, sementara for_each
itu lebih fleksibel.
The for_each
Loop dimaksudkan untuk menyembunyikan iterator (detail dari bagaimana lingkaran diimplementasikan) dari kode pengguna dan mendefinisikan semantik yang jelas tentang operasi: setiap elemen akan mengulangi tepat sekali.
Masalah dengan keterbacaan dalam standar saat ini adalah bahwa ia membutuhkan functor sebagai argumen terakhir alih-alih blok kode, jadi dalam banyak kasus Anda harus menulis jenis functor khusus untuk itu. Itu berubah menjadi kode yang kurang dapat dibaca sebagai objek functor tidak dapat didefinisikan di tempat (kelas lokal yang didefinisikan dalam fungsi tidak dapat digunakan sebagai argumen templat) dan implementasi loop harus dipindahkan dari loop aktual.
struct myfunctor {
void operator()( int arg1 ) { code }
};
void apply( std::vector<int> const & v ) {
// code
std::for_each( v.begin(), v.end(), myfunctor() );
// more code
}
Perhatikan bahwa jika Anda ingin melakukan operasi tertentu pada setiap objek, Anda dapat menggunakan std::mem_fn
, atau boost::bind
( std::bind
dalam standar berikutnya), atau boost::lambda
(lambda dalam standar berikutnya) untuk membuatnya lebih sederhana:
void function( int value );
void apply( std::vector<X> const & v ) {
// code
std::for_each( v.begin(), v.end(), boost::bind( function, _1 ) );
// code
}
Yang tidak lebih mudah dibaca dan lebih ringkas daripada versi linting tangan jika Anda memang memiliki fungsi / metode untuk memanggilnya. Implementasi dapat memberikan implementasi for_each
loop lainnya (pikirkan pemrosesan paralel).
Standar yang akan datang menangani beberapa kekurangan dengan cara yang berbeda, itu akan memungkinkan kelas yang didefinisikan secara lokal sebagai argumen untuk templat:
void apply( std::vector<int> const & v ) {
// code
struct myfunctor {
void operator()( int ) { code }
};
std::for_each( v.begin(), v.end(), myfunctor() );
// code
}
Meningkatkan lokalitas kode: ketika Anda menjelajah Anda melihat apa yang dilakukannya di sana. Faktanya, Anda bahkan tidak perlu menggunakan sintaks kelas untuk mendefinisikan functor, tetapi gunakan lambda di sana:
void apply( std::vector<int> const & v ) {
// code
std::for_each( v.begin(), v.end(),
[]( int ) { // code } );
// code
}
Bahkan jika untuk kasus for_each
akan ada konstruksi spesifik yang akan membuatnya lebih alami:
void apply( std::vector<int> const & v ) {
// code
for ( int i : v ) {
// code
}
// code
}
Saya cenderung mencampur for_each
konstruk dengan loop linting tangan. Ketika hanya panggilan ke fungsi atau metode yang ada adalah apa yang saya butuhkan ( for_each( v.begin(), v.end(), boost::bind( &Type::update, _1 ) )
) saya pergi untuk for_each
membangun yang mengambil dari kode banyak hal-hal iterator plat ketel. Ketika saya membutuhkan sesuatu yang lebih kompleks dan saya tidak dapat mengimplementasikan functor hanya beberapa baris di atas penggunaan aktual, saya menggulung loop saya sendiri (menjaga operasi tetap di tempat). Di bagian kode yang tidak kritis, saya mungkin menggunakan BOOST_FOREACH (rekan kerja memasukkan saya ke dalamnya)
Selain keterbacaan dan kinerja, satu aspek yang sering diabaikan adalah konsistensi. Ada banyak cara untuk mengimplementasikan loop over iterator for (atau sementara), dari:
for (C::iterator iter = c.begin(); iter != c.end(); iter++) {
do_something(*iter);
}
untuk:
C::iterator iter = c.begin();
C::iterator end = c.end();
while (iter != end) {
do_something(*iter);
++iter;
}
dengan banyak contoh di antaranya pada berbagai tingkat efisiensi dan potensi bug.
Menggunakan for_each, bagaimanapun, menegakkan konsistensi dengan mengabstraksi loop:
for_each(c.begin(), c.end(), do_something);
Satu-satunya hal yang harus Anda khawatirkan sekarang adalah: apakah Anda mengimplementasikan loop body sebagai fungsi, functor, atau lambda menggunakan fitur Boost atau C ++ 0x? Secara pribadi, saya lebih suka khawatir tentang itu daripada bagaimana menerapkan atau membaca secara acak untuk / while.
Saya dulu tidak suka std::for_each
dan berpikir bahwa tanpa lambda, itu dilakukan dengan sangat salah. Namun saya berubah pikiran beberapa waktu yang lalu, dan sekarang saya benar-benar menyukainya. Dan saya pikir itu bahkan meningkatkan keterbacaan, dan membuatnya lebih mudah untuk menguji kode Anda dengan cara TDD.
The std::for_each
algoritma dapat dibaca sebagai do sesuatu dengan semua elemen dalam jangkauan , yang dapat meningkatkan keterbacaan. Katakan tindakan yang ingin Anda lakukan sepanjang 20 baris, dan fungsi di mana tindakan dilakukan juga sekitar 20 baris. Itu akan membuat fungsi 40 baris panjang dengan loop konvensional, dan hanya sekitar 20 baris std::for_each
, sehingga lebih mudah dipahami.
Functors untuk std::for_each
lebih cenderung lebih umum, dan dengan demikian dapat digunakan kembali, misalnya:
struct DeleteElement
{
template <typename T>
void operator()(const T *ptr)
{
delete ptr;
}
};
Dan dalam kode Anda hanya akan memiliki satu-liner seperti std::for_each(v.begin(), v.end(), DeleteElement())
yang sedikit lebih baik IMO daripada loop eksplisit.
Semua functors itu biasanya lebih mudah untuk mendapatkan di bawah unit test daripada eksplisit untuk loop di tengah fungsi yang panjang, dan itu saja sudah merupakan kemenangan besar bagi saya.
std::for_each
juga umumnya lebih dapat diandalkan, karena Anda cenderung membuat kesalahan dengan jangkauan.
Dan terakhir, kompiler mungkin menghasilkan kode yang sedikit lebih baik std::for_each
daripada untuk jenis-jenis kerajinan tangan tertentu untuk loop, karena (for_each) selalu terlihat sama untuk kompiler, dan penulis kompiler dapat menaruh semua pengetahuan mereka, untuk membuatnya sebagus mereka bisa.
Hal yang sama berlaku untuk algoritma std lain seperti find_if
, transform
dll.
for
adalah untuk loop yang dapat mengulangi setiap elemen atau setiap ketiga dll for_each
adalah untuk hanya mengulangi setiap elemen. Jelas dari namanya. Jadi lebih jelas apa yang ingin Anda lakukan dalam kode Anda.
++
. Mungkin tidak biasa, tetapi begitu juga untuk loop melakukan hal yang sama.
transform
untuk tidak membingungkan seseorang.
Jika Anda sering menggunakan algoritma lain dari STL, ada beberapa keuntungan untuk for_each
:
Tidak seperti tradisional untuk loop, for_each
memaksa Anda untuk menulis kode yang akan bekerja untuk setiap iterator input. Dibatasi dengan cara ini sebenarnya bisa menjadi hal yang baik karena:
for_each
.Menggunakan for_each
kadang-kadang membuatnya lebih jelas bahwa Anda dapat menggunakan fungsi STL yang lebih spesifik untuk melakukan hal yang sama. (Seperti dalam contoh Jerry Coffin; itu belum tentu kasus yang for_each
merupakan pilihan terbaik, tetapi untuk loop bukan satu-satunya alternatif.)
Dengan C ++ 11 dan dua templat sederhana, Anda dapat menulis
for ( auto x: range(v1+4,v1+6) ) {
x*=2;
cout<< x <<' ';
}
sebagai pengganti for_each
atau loop. Mengapa memilih itu bermuara pada singkatnya dan keamanan, tidak ada kemungkinan kesalahan dalam ekspresi yang tidak ada.
Bagi saya, for_each
selalu lebih baik dengan alasan yang sama ketika loop body sudah merupakan functor, dan saya akan mengambil keuntungan apa pun yang bisa saya dapatkan.
Anda masih menggunakan tiga-ekspresi for
, tetapi sekarang ketika Anda melihat satu Anda tahu ada sesuatu yang perlu dipahami di sana, itu bukan boilerplate. Aku benci piring. Saya membenci keberadaannya. Ini bukan kode nyata, tidak ada yang bisa dipelajari dengan membacanya, itu hanya satu hal lagi yang perlu diperiksa. Upaya mental dapat diukur dengan seberapa mudah berkarat dalam memeriksanya.
Templatnya adalah
template<typename iter>
struct range_ {
iter begin() {return __beg;} iter end(){return __end;}
range_(iter const&beg,iter const&end) : __beg(beg),__end(end) {}
iter __beg, __end;
};
template<typename iter>
range_<iter> range(iter const &begin, iter const &end)
{ return range_<iter>(begin,end); }
Sebagian besar Anda harus mengulang seluruh koleksi . Karena itu saya sarankan Anda menulis varian for_each () Anda sendiri, dengan hanya mengambil 2 parameter. Ini akan memungkinkan Anda untuk menulis ulang contoh Terry Mahaffey sebagai:
for_each(container, [](int& i) {
i += 10;
});
Saya pikir ini memang lebih mudah dibaca daripada for loop. Namun, ini membutuhkan ekstensi kompiler C ++ 0x.
Saya menemukan for_each buruk untuk keterbacaan. Konsepnya bagus, tetapi c ++ membuatnya sangat sulit untuk ditulis, setidaknya bagi saya. c ++ ekspresi 0x lamda akan membantu. Saya sangat menyukai gagasan para lama. Namun pada pandangan pertama saya pikir sintaksinya sangat jelek dan saya tidak 100% yakin saya akan pernah terbiasa dengannya. Mungkin dalam 5 tahun saya akan terbiasa dan tidak memikirkannya lagi, tapi mungkin tidak. Waktu akan menjawab :)
Saya lebih suka menggunakan
vector<thing>::iterator istart = container.begin();
vector<thing>::iterator iend = container.end();
for(vector<thing>::iterator i = istart; i != iend; ++i) {
// Do stuff
}
Saya menemukan eksplisit untuk loop lebih jelas untuk membaca dan explicity menggunakan variabel bernama untuk memulai dan mengakhiri iterators mengurangi kekacauan dalam for loop.
Tentu saja kasus bervariasi, ini hanya apa yang biasanya saya temukan yang terbaik.
Anda dapat membuat iterator menjadi panggilan ke fungsi yang dilakukan pada setiap iterasi melalui loop.
Lihat di sini: http://www.cplusplus.com/reference/algorithm/for_each/
for_each
dilakukannya, dalam hal ini, ia tidak menjawab pertanyaan tentang kelebihannya.
Untuk loop bisa putus; Saya tidak ingin menjadi burung beo untuk Herb Sutter jadi di sini ada tautan ke presentasinya: http://channel9.msdn.com/Events/BUILD/BUILD2011/TOOL-835T Pastikan untuk membaca komentar juga :)
for_each
memungkinkan kita untuk menerapkan pola Fork-Join . Selain itu mendukung antarmuka yang lancar .
Kita dapat menambahkan implementasi gpu::for_each
untuk menggunakan cuda / gpu untuk komputasi paralel-heterogen dengan memanggil tugas lambda di banyak pekerja.
gpu::for_each(users.begin(),users.end(),update_summary);
// all summary is complete now
// go access the user-summary here.
Dan gpu::for_each
mungkin menunggu pekerja menyelesaikan semua tugas lambda sebelum menyelesaikan pernyataan berikutnya.
Itu memungkinkan kita untuk menulis kode yang bisa dibaca manusia dengan cara ringkas.
accounts::erase(std::remove_if(accounts.begin(),accounts.end(),used_this_year));
std::for_each(accounts.begin(),accounts.end(),mark_dormant);
std::for_each
ketika digunakan denganboost.lambda
atauboost.bind
sering dapat meningkatkan keterbacaan