Utilizza sempre la variante che descrive meglio cosa intendi fare. Questo è
For each element x
in vec
, do bar.process(x)
.
Ora esaminiamo gli esempi:
std::for_each(vec.begin(), vec.end(),
std::bind1st(std::mem_fun_ref(&Bar::process), bar));
Anche lì abbiamo un for_each
- yippeh . Abbiamo l'intervallo [begin; end)
su cui vogliamo operare.
In linea di principio, l'algoritmo era molto più esplicito e quindi preferibile rispetto a qualsiasi implementazione scritta a mano. Ma poi ... Binders? Memfun? Fondamentalmente C ++ interna di come entrare in possesso di una funzione membro? Per il mio compito, Non mi interessa su di loro! Né voglio soffrire di questa verbosa sintassi inquietante.
Ora l'altra possibilità:
for (std::vector<Foo>::const_iterator it = vec.begin(); it != vec.end(); ++it)
{
bar.process(*it);
}
Certo, questo è un modello comune per riconoscere, ma ... creare iteratori, loop, incrementare, dereferenziare. Anche queste sono tutte cose a cui non mi interessa per poter svolgere il mio compito.
Certo, sembra migliore della prima soluzione (almeno, il ciclo body è flessibile e abbastanza esplicito), ma ancora, non è quello fantastico. Useremo questo se non avessimo possibilità migliori, ma forse abbiamo ...
Un modo migliore?
Ora torna a for_each
. Non sarebbe bello dire letteralmente for_each
e essere flessibili nell'operazione che deve essere fatta anche tu? Fortunatamente, dal momento che C ++ 0x lambda, siamo
for_each(v.begin(), v.end(), [&](const Foo& x) { bar.process(x); })
Ora che abbiamo trovato una soluzione generica e astratta a molte situazioni correlate, vale la pena notare che in questo caso particolare, esiste un # 1 favorite :
foreach(const Foo& x, vec) bar.process(x);
In realtà non può essere molto più chiaro di quello. Per fortuna, C ++ 0x ha una sintassi simile built-in !