std::for_each
Aşırı for
döngü avantajları var mı? Bana göre, std::for_each
sadece kodun okunabilirliğini engelliyor gibi görünüyor. O zaman neden bazı kodlama standartları kullanılmasını öneriyor?
std::for_each
Aşırı for
döngü avantajları var mı? Bana göre, std::for_each
sadece kodun okunabilirliğini engelliyor gibi görünüyor. O zaman neden bazı kodlama standartları kullanılmasını öneriyor?
Yanıtlar:
C ++ 11 (daha önce C ++ 0x olarak adlandırılıyordu) ile güzel bir şey , bu yorucu tartışmanın çözülecek olmasıdır.
Demek istediğim, bütün bir koleksiyon üzerinde yinelemek isteyen doğru akıllarında olan hiç kimse bunu kullanmayacak
for(auto it = collection.begin(); it != collection.end() ; ++it)
{
foo(*it);
}
Veya bu
for_each(collection.begin(), collection.end(), [](Element& e)
{
foo(e);
});
zaman aralığı tabanlı for
döngü sözdizimi mevcuttur:
for(Element& e : collection)
{
foo(e);
}
Bu tür bir sözdizimi bir süredir Java ve C # 'da mevcuttu ve aslında gördüğüm her Java veya C # kodunda foreach
klasik for
döngülerden çok daha fazla döngü var .
Element & e
olarak auto & e
(veya auto const &e
) iyi görünüyor. Bana kalırsa doğru Element const e
ben örtük dönüştürme istediğinizde, kaynak farklı türde bir koleksiyon olduğu zaman söylemek ve onları dönüştürmek istediğiniz (referans olmadan) Element
.
İşte bazı nedenleri:
Sadece buna alışık olmadığınız ve / veya gerçekten kolay olması için etrafındaki doğru araçları kullanmadığınız için okunabilirliği engelliyor gibi görünüyor. (yardımcılar için boost :: range and boost :: bind / boost :: lambda'ya bakın. Bunların çoğu C ++ 0x'e girecek ve for_each ve ilgili işlevleri daha kullanışlı hale getirecektir.)
Herhangi bir yineleyici ile çalışan for_each üzerine bir algoritma yazmanıza izin verir.
Aptalca yazma hataları olasılığını azaltır.
Aynı zamanda, böyle STL-algoritmaları geri kalanına zihninizi açar find_if
, sort
, replace
vb ve bu artık o kadar tuhaf bakmayacak. Bu büyük bir kazanç olabilir.
Güncelleme 1:
En önemlisi, for_each
her şey var gibi for-loop'ların ötesine geçmenize ve find / sort / partition / copy_replace_if, paralel yürütme .. veya başka bir şey gibi diğer STL-aloglarına bakmanıza yardımcı olur .
For_each'ın kardeşlerinin "geri kalanı" kullanılarak çok fazla işlem çok kısaca yazılabilir, ancak yaptığınız tek şey çeşitli dahili mantıkla bir for-loop yazmaksa, bunları nasıl kullanacağınızı asla öğrenemezsiniz ve sonunda tekerleği tekrar tekrar icat etti.
Ve (her biri için yakında kullanıma sunulacak aralık stili):
for_each(monsters, boost::mem_fn(&Monster::think));
Veya C ++ x11 lambdas ile:
for_each(monsters, [](Monster& m) { m.think(); });
IMO şunlardan daha okunabilir:
for(Monsters::iterator i = monsters.begin(); i != monsters.end(); ++i) {
i->think();
}
Ayrıca bu (veya lambdas ile, diğerlerine bakın):
for_each(bananas, boost::bind(&Monkey::eat, my_monkey, _1));
Şunlardan daha özlü:
for(Bananas::iterator i = bananas.begin(); i != bananas.end(); ++i) {
my_monkey->eat(*i);
}
Özellikle sırayla arayabileceğiniz birkaç fonksiyonunuz varsa ... ama belki bu sadece benim. ;)
Güncelleme 2 : Yineleyiciler yerine aralıklarla çalışan kendi tek katlı stl-algos sarmalayıcılarımı yazdım. boost :: range_ex, piyasaya sürüldükten sonra, bunu içerecek ve belki de C ++ 0x'de olacak mı?
outer_class::inner_class::iterator
ya da şablon argümanlarıdır: typename std::vector<T>::iterator
... for yapısının kendisi kendi içinde birçok çizgi yapısına girebilir
for_each
ikinci örnekte yanlış (olması gerekirfor_each( bananas.begin(), bananas.end(),...
for_each
daha geneldir. Herhangi bir konteyner türünü yinelemek için kullanabilirsiniz (başlangıç / bitiş yineleyicilerini ileterek). for_each
Yineleme kodunu güncellemek zorunda kalmadan kullanılan bir işlevin altındaki kapları değiştirebilirsiniz . std::vector
Avantajları görmek için dünyada daha başka konteynerler ve düz eski C dizileri olduğunu düşünmelisiniz .for_each
.
En büyük dezavantajı for_each
bir işlev almasıdır, bu yüzden sözdizimi tıknazdır. Bu, lambdas'ın girişiyle C ++ 11'de (eski adıyla C ++ 0x) düzeltildi:
std::vector<int> container;
...
std::for_each(container.begin(), container.end(), [](int& i){
i+= 10;
});
Bu 3 yıl içinde size garip gelmeyecek.
for ( int v : int_vector ) {
(bugün BOOST_FOREACH ile simüle edilebilse bile)
std::for_each(container, [](int& i){ ... });
. Demek istediğim biri neden iki kez kap yazmaya zorlanıyor?
container.each { ... }
ve bitiş yineleyicilerinden bahsetmeden benzer bir şey yazıyor . Ben son yineleyici her zaman belirtmek zorunda biraz gereksiz buluyorum.
Şahsen, kullanmak için yolumdan çıkmak istediğim her zaman std::for_each
(özel amaçlı functors / komplike boost::lambda
s yazma ), BOOST_FOREACH
daha net bulmak için C ++ 0x aralığını buluyorum :
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)));
çok öznel, bazıları kullanmanın for_each
kodu aynı sözleşmelerle farklı koleksiyonları işlemeye izin verdiği için kodu daha okunabilir hale getireceğini söyleyecektir .
for_each
itslef bir döngü olarak uygulanır
template<class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function f)
{
for ( ; first!=last; ++first ) f(*first);
return f;
}
sizin için neyin doğru olduğunu seçmek size kalmış.
Algoritma işlevlerinin çoğu gibi, ilk tepki, foreach kullanmanın bir döngüden daha okunaksız olduğunu düşünmektir. Birçok alev savaşının konusu oldu.
Deyime alıştıktan sonra yararlı bulabilirsiniz. Bariz bir avantaj, kodlayıcının, halkanın iç içeriğini gerçek yineleme işlevselliğinden ayırmaya zorlamasıdır. (Tamam, bence bu bir avantaj. Diğerleri sadece gerçek bir faydası olmadan kodu parçaladığını söylüyor).
Diğer bir avantajı ise, her şeyi gördüğümde biliyorum her öğe ya işlenecektir veya bir özel durum olacağı.
A için döngü döngü sonlandırma için çeşitli seçenekler sağlar. Döngünün tam yolunu çalıştırmasına izin verebilir veya döngüden açıkça atlamak için break anahtar sözcüğünü kullanabilir veya tüm işlev orta döngüden çıkmak için return anahtar sözcüğünü kullanabilirsiniz . Aksine, foreach bu seçeneklere izin vermez ve bu da daha okunabilir olmasını sağlar. Sadece işlev adına bakabilir ve yinelemenin tam doğasını bilirsiniz.
İşte döngü için kafa karıştırıcı bir örnek :
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()
(bu yazının zamanın) eski standardında Eğer dediğin gibi okunabilirliği teşvik eder ve döngü erken patlak yasaklayan adlandırılmış functor, kullanmak zorunda. Ama sonra eşdeğer for
döngü bir işlev çağrısından başka bir şeye sahip değildir ve bu da erken çıkmayı yasaklar. Ama bunun dışında , tüm menzil boyunca std::for_each()
zorlamaların olduğunu söylerken mükemmel bir noktaya değindiğini düşünüyorum .
Çoğunlukla haklısın: çoğu zaman std::for_each
net bir kayıp. Şimdiye kadar karşılaştırmak için gider for_each
için goto
. goto
mümkün olan en çok yönlü akış kontrolünü sağlar - hayal edebileceğiniz diğer tüm kontrol yapılarını uygulamak için kullanabilirsiniz. Bununla birlikte, bu çok yönlülük, goto
izole bir şekilde görmenin , bu durumda ne yapılması gerektiği hakkında neredeyse hiçbir şey söylemediği anlamına gelir . Sonuç olarak, sağ akıllarında neredeyse hiç kimse kullanmıyorgoto
son çare dışında .
Standart algoritmalar arasında, for_each
neredeyse aynı yol vardır - neredeyse her şeyi uygulamak için kullanılabilir, yani görme for_each
bu durumda ne için kullanıldığı hakkında neredeyse hiçbir şey söylemez. Ne yazık ki, insanların tutumu for_each
, goto
1970'e ya da daha fazlasına yönelik tutumlarının nerede olduğu ile ilgilidir - birkaç kişi, sadece son çare olarak kullanılması gerektiği gerçeğini yakaladı, ancak birçoğu hala birincil algoritma olduğunu düşünüyor ve nadiren başka birini kullanırsanız. Zamanın büyük çoğunluğu, hızlı bir bakışta bile, alternatiflerden birinin büyük ölçüde üstün olduğunu ortaya çıkaracaktır.
Sadece örneğin, bir koleksiyon içeriğini kullanarak yazdırmak için insanların kaç kez kod yazdığını gördüm izini kaybettim eminim for_each
. Gördüğüm yayınlara dayanarak, bu en yaygın kullanımı olabilir for_each
. Sonunda şöyle bir şey ortaya çıkıyor:
class XXX {
// ...
public:
std::ostream &print(std::ostream &os) { return os << "my data\n"; }
};
Ve onların sonrası hangi kombinasyonu soruyor bind1st
, mem_fun
vb onlar gibi bir şey yapmak gerekir:
std::vector<XXX> coll;
std::for_each(coll.begin(), coll.end(), XXX::print);
çalışın ve unsurlarını yazdırın coll
. Eğer tam olarak orada yazdığım gibi çalışsaydı, vasat olurdu, ama işe yaramaz - ve işe yaradığınızda, ne ile ilgili bu birkaç kod parçasını bulmak zor bir arada tutan parçalar arasında devam ediyor.
Neyse ki, çok daha iyi bir yol var. XXX için normal bir akış ekleyicisi aşırı yüklemesi ekleyin:
std::ostream &operator<<(std::ostream *os, XXX const &x) {
return x.print(os);
}
ve kullanın std::copy
:
std::copy(coll.begin(), coll.end(), std::ostream_iterator<XXX>(std::cout, "\n"));
Bu işe yarar - ve içeriğini yazdırdığını anlamak için neredeyse hiç çalışma coll
gerektirmez std::cout
.
boost::mem_fn(&XXX::print)
ziyade olmalıXXX::print
std::cout
için argümanı olarak da bağlamanız gerekiyor ).
Arıcılık için işlevsel yazmanın avantajı daha okunabilir, ne zaman for(...)
ve görünmeyebilir for_each(...
).
Tüm algoritmaları function.h dosyasında for-loop kullanmak yerine kullanırsanız, kod çok daha okunabilir hale gelir;
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);
bir çok daha okunabilir birden;
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);
}
Ve bu kadar güzel olduğunu düşünüyorum, for-loop'ları bir satır fonksiyonuna genelleştirin =)
Kolay: for_each
Her dizi öğesini işleyecek bir işleve sahip olduğunuzda kullanışlıdır, bu nedenle bir lambda yazmak zorunda kalmazsınız. Şüphesiz, bu
for_each(a.begin(), a.end(), a_item_handler);
daha iyi
for(auto& item: a) {
a_item_handler(a);
}
Ayrıca, aralıklı for
döngü yalnızca tüm kaplar üzerinde baştan sona yinelenir for_each
, daha esnektir.
for_each
Döngü işlemi ile açık anlamlara kullanıcı kodu yineleyicileri (bir döngü nasıl uygulandığını detay) gizlemek ve tanımlamak için demek: her eleman sadece bir kere tekrarlanır edilecektir.
Mevcut standartta okunabilirlik sorunu, bir kod bloğu yerine son argüman olarak bir functor gerektirmesidir, bu nedenle çoğu durumda bunun için belirli functor türü yazmanız gerekir. Functor nesneleri yerinde tanımlanamadığından (işlev içinde tanımlanan yerel sınıflar şablon bağımsız değişkenleri olarak kullanılamaz) ve döngünün uygulamasının gerçek döngüden taşınması gerektiğinden, daha az okunabilir koda dönüşür.
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
}
Her nesne üzerinde bir spesifik işlemi gerçekleştirmek istiyorsanız, kendinizin kullanabileceği Not std::mem_fn
veya boost::bind
( std::bind
sonraki standardında) veya boost::lambda
(sonraki standartta lambda'lar) daha basit hale getirmek için:
void function( int value );
void apply( std::vector<X> const & v ) {
// code
std::for_each( v.begin(), v.end(), boost::bind( function, _1 ) );
// code
}
Eğer yerine çağıracak fonksiyon / yöntem varsa el haddelenmiş sürümü daha az okunabilir ve daha kompakt değildir. Uygulama, for_each
döngünün diğer uygulamalarını sağlayabilir (paralel işlem düşünün).
Yaklaşan standart, bazı eksiklikleri farklı şekillerde ele alır, yerel olarak tanımlanan sınıfların şablonlara argüman olarak izin verir:
void apply( std::vector<int> const & v ) {
// code
struct myfunctor {
void operator()( int ) { code }
};
std::for_each( v.begin(), v.end(), myfunctor() );
// code
}
Kodun yerinin iyileştirilmesi: göz attığınızda kodun orada ne yaptığını görürsünüz. Aslında, functor'ı tanımlamak için sınıf sözdizimini kullanmanıza bile gerek yoktur, ancak burada bir lambda kullanın:
void apply( std::vector<int> const & v ) {
// code
std::for_each( v.begin(), v.end(),
[]( int ) { // code } );
// code
}
Durum for_each
için daha doğal hale getirecek belirli bir yapı olsa bile :
void apply( std::vector<int> const & v ) {
// code
for ( int i : v ) {
// code
}
// code
}
Yapıyı for_each
elle haddelenmiş döngülerle karıştırma eğilimindeyim . Sadece mevcut bir fonksiyon veya yöntem için bir çağrı ne gerek ( for_each( v.begin(), v.end(), boost::bind( &Type::update, _1 ) )
) Ben for_each
kod plaka kazanı yineleyici şeyler bir sürü alır yapı için gitmek . Daha karmaşık bir şeye ihtiyacım olduğunda ve gerçek kullanımın sadece birkaç satırının üstünde bir işlev uygulayamıyorsam, kendi döngümü yuvarlıyorum (işlemi yerinde tutar). Kodun kritik olmayan bölümlerinde BOOST_FOREACH ile gidebilirim (bir iş arkadaşı beni içine aldı)
Okunabilirlik ve performansın yanı sıra, yaygın şekilde göz ardı edilen bir husus da tutarlılıktır. Yineleyiciler üzerinde for (veya while) döngüsünü uygulamanın birçok yolu vardır:
for (C::iterator iter = c.begin(); iter != c.end(); iter++) {
do_something(*iter);
}
için:
C::iterator iter = c.begin();
C::iterator end = c.end();
while (iter != end) {
do_something(*iter);
++iter;
}
değişken verimlilik seviyeleri ve hata potansiyeli arasında birçok örnek.
Ancak for_each komutunun kullanılması, döngüyü soyutlayarak tutarlılığı zorunlu kılar:
for_each(c.begin(), c.end(), do_something);
Şimdi endişelenmeniz gereken tek şey, döngü gövdesini Boost veya C ++ 0x özelliklerini kullanarak işlev, işlev veya lambda olarak mı uyguluyorsunuz? Şahsen, bunun için bir rastgele / while döngüsü nasıl uygulanacağından veya okunacağından endişe ediyorum.
Sevmezdim std::for_each
ve lambda olmadan tamamen yanlış yapıldığını düşündüm. Ancak bir süre önce fikrimi değiştirdim ve şimdi gerçekten seviyorum. Bence okunabilirliği bile geliştiriyor ve kodunuzu bir TDD yöntemiyle test etmeyi kolaylaştırıyor.
std::for_each
Algoritma olarak okunabilir aralığındaki tüm unsurları ile do şey , olabilir okunabilirliği artırmak. Gerçekleştirmek istediğiniz eylemin 20 satır uzunluğunda olduğunu ve eylemin gerçekleştirildiği işlevin de yaklaşık 20 satır uzunluğunda olduğunu varsayalım. Bu, geleneksel bir döngü ile 40 satır uzunluğunda ve sadece yaklaşık 20 ile bir işlevi yapar std::for_each
, böylece anlaşılması daha kolay olur.
Functor'larının std::for_each
daha genel olma olasılığı daha yüksektir ve bu nedenle tekrar kullanılabilir, örneğin:
struct DeleteElement
{
template <typename T>
void operator()(const T *ptr)
{
delete ptr;
}
};
Ve kodda sadece bir astar var std::for_each(v.begin(), v.end(), DeleteElement())
açık bir döngüden biraz daha iyi bir IMO .
Bu işlevlerin tümü, uzun bir fonksiyonun ortasında bir döngü için açık olandan ziyade birim testlere girmek için daha kolaydır ve bu tek başına zaten benim için büyük bir kazançtır.
std::for_each
menzil ile ilgili bir hata yapma olasılığınız düşük olduğu için genellikle daha güvenilirdir.
Ve son olarak, derleyici std::for_each
, döngü için el yapımı belirli türlere göre biraz daha iyi kod üretebilir , çünkü (for_each) derleyici için her zaman aynı görünür ve derleyici yazarları tüm bilgilerini koyabilirler. Yapabilmek.
Aynısı find_if
, transform
vb. Gibi diğer std algoritmaları için de geçerlidir .
for
her öğeyi veya her üçte birini yineleyebilen döngü içindir vb for_each
. her öğeyi yinelemek içindir. Adından açıkça anlaşılıyor. Bu yüzden kodunuzda ne yapmak istediğinizi daha açık.
++
. Alışılmadık belki, ama aynı şeyi yapan bir for-loop da öyle.
transform
birisini karıştırmamak için kullanmak daha iyi olacaktır .
STL'nin diğer algoritmalarını sık sık kullanıyorsanız, aşağıdakilerin birkaç avantajı vardır for_each
:
Geleneksel bir for döngüsünden farklı olarak, for_each
herhangi bir giriş yineleyicisi için çalışacak kodu yazmaya zorlar. Bu şekilde kısıtlanmak aslında iyi bir şey olabilir çünkü:
for_each
.Kullanılması for_each
bazen aynı şeyi yapmak için daha spesifik bir STL fonksiyonunu kullanabilirsiniz o daha belirgin hale getirir. (Jerry Coffin'in örneğinde olduğu gibi; en for_each
iyi seçenek bu olmak zorunda değildir , ancak bir for döngüsü tek alternatif değildir.)
C ++ 11 ve iki basit şablonla,
for ( auto x: range(v1+4,v1+6) ) {
x*=2;
cout<< x <<' ';
}
yerine for_each
veya bir döngü olarak. Neden kısalık ve güvenliğe dayanacağını seçin, orada olmayan bir ifadede hata şansı yoktur.
Benim için, for_each
döngü gövdesi zaten bir functor olduğunda aynı gerekçelerle her zaman daha iyiydi ve elde edebileceğim herhangi bir avantajdan yararlanacağım.
Üç ifadeyi hala kullanıyorsunuz for
, ancak şimdi bir tanesini gördüğünüzde orada anlayacağınız bir şey olduğunu biliyorsunuz, kaynak plakası değil. Ben nefret klişe. Onun varlığına kızdım. Gerçek kod değil, okuyarak öğrenecek bir şey yok, kontrol edilmesi gereken bir şey daha var. Zihinsel çaba, onu kontrol etmede paslanmanın ne kadar kolay olduğu ile ölçülebilir.
Şablonlar
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); }
Çoğunlukla tüm koleksiyonu yinelemeniz gerekir . Bu nedenle, sadece 2 parametre alarak kendi for_each () değişkeninizi yazmanızı öneririm. Bu, Terry Mahaffey'in örneğini şöyle yeniden yazmanıza izin verecektir :
for_each(container, [](int& i) {
i += 10;
});
Bu gerçekten bir for döngüsünden daha okunabilir olduğunu düşünüyorum. Ancak, bu C ++ 0x derleyici uzantıları gerektirir.
For_each'un okunabilirlik açısından kötü olduğunu düşünüyorum. Konsept iyi bir şey ama c ++ en azından benim için okunabilirliği zorlaştırıyor. c ++ 0x lamda ifadeleri yardımcı olacaktır. Lamdalar fikrini çok seviyorum. Ancak ilk bakışta sözdiziminin çok çirkin olduğunu düşünüyorum ve buna alışacağımdan% 100 emin değilim. Belki 5 yıl içinde buna alıştım ve ikinci bir düşünce vermeyeceğim, ama belki de yapmayacağım. Zaman gösterecek :)
Kullanmayı tercih ederim
vector<thing>::iterator istart = container.begin();
vector<thing>::iterator iend = container.end();
for(vector<thing>::iterator i = istart; i != iend; ++i) {
// Do stuff
}
Başlangıç ve bitiş yineleyicileri için adlandırılmış değişkenler kullanarak döngü temizleyici okumak ve açıklık için açık bir bulmak için for döngüsü dağınıklığı azaltır.
Tabii ki durumlar değişir, genellikle en iyi bulduğum şey budur.
Yineleyiciyi döngü üzerinden her yinelemede gerçekleştirilen bir işleve çağrı yapabilirsiniz.
Buraya bakın: http://www.cplusplus.com/reference/algorithm/for_each/
for_each
işe yaradığını özetlersiniz , bu durumda avantajları hakkındaki soruya cevap vermez.
Döngü kırılabilir için; Herb Sutter için papağan olmak istemiyorum, bu yüzden sunumuna bağlantı: http://channel9.msdn.com/Events/BUILD/BUILD2011/TOOL-835T Ayrıca yorumları da okuyun :)
for_each
Fork-Join modelini uygulamamıza izin verin . Bunun dışında akıcı arayüzü destekler .
gpu::for_each
Birden fazla çalışanda lambda görevini çağırarak heterojen paralel hesaplama için cuda / gpu kullanmak için uygulama ekleyebiliriz .
gpu::for_each(users.begin(),users.end(),update_summary);
// all summary is complete now
// go access the user-summary here.
Ve gpu::for_each
işçilerin bir sonraki ifadeleri çalıştırmadan önce tüm lambda görevleri üzerinde çalışmasını bekleyebilir.
İnsan tarafından okunabilen kodu kısa ve öz bir şekilde yazmamızı sağlar.
accounts::erase(std::remove_if(accounts.begin(),accounts.end(),used_this_year));
std::for_each(accounts.begin(),accounts.end(),mark_dormant);
std::for_each
ile kullanıldığındaboost.lambda
veyaboost.bind
genellikle okunabilirliği artırabilir