Zawsze używaj wariantu, który najlepiej opisuje to , co zamierzasz zrobić. To jest
Dla każdego elementu x
w vec
, wykonaj bar.process(x)
.
Teraz przeanalizujmy przykłady:
std::for_each(vec.begin(), vec.end(),
std::bind1st(std::mem_fun_ref(&Bar::process), bar));
My też for_each
tam mamy - yippeh . Mamy [begin; end)
zasięg, na którym chcemy operować.
Zasadniczo algorytm był znacznie bardziej wyraźny i dlatego był lepszy niż jakakolwiek ręczna implementacja. Ale potem ... Segregatory? Memfun? Zasadniczo C ++ interna jak uzyskać funkcję członka? W moim zadaniu nie dbam o nie! Nie chcę też cierpieć z powodu tej pełnej, przerażającej składni.
Teraz inna możliwość:
for (std::vector<Foo>::const_iterator it = vec.begin(); it != vec.end(); ++it)
{
bar.process(*it);
}
To prawda, że jest to powszechny wzorzec rozpoznawania, ale ... tworzenie iteratorów, zapętlanie, inkrementacja, dereferencje. To także są rzeczy , których nie obchodzi mnie , aby wykonać swoje zadanie.
Trzeba przyznać, że wygląda lepiej niż waay pierwszego rozwiązania (przynajmniej, pętla ciało jest elastyczne i dość wyraźny), ale nadal, to naprawdę nie jest , że świetnie. Użyjemy tego, jeśli nie mielibyśmy lepszych możliwości, ale może mamy ...
Lepszy sposób?
Teraz z powrotem do for_each
. Czy nie byłoby wspaniale powiedzieć for_each
i być elastycznym w operacjach, które należy wykonać? Na szczęście, odkąd C ++ 0x lambdas, jesteśmy
for_each(v.begin(), v.end(), [&](const Foo& x) { bar.process(x); })
Teraz, gdy znaleźliśmy abstrakcyjne, ogólne rozwiązanie wielu powiązanych sytuacji, warto zauważyć, że w tym konkretnym przypadku istnieje absolutnie ulubiony numer 1 :
foreach(const Foo& x, vec) bar.process(x);
Naprawdę nie może być dużo jaśniejszego niż to. Na szczęście, C ++ 0x get podobna składnia wbudowanej !
map(bar.process, vec)
chociaż mapa efektów ubocznych jest odradzana, a lista wyrażeń / wyrażeń generatora jest zalecana zamiast mapy).