Всегда используйте вариант, который лучше всего описывает то, что вы собираетесь делать. Это
Для каждого элемента x
в vec
do bar.process(x)
.
Теперь давайте рассмотрим примеры:
std::for_each(vec.begin(), vec.end(),
std::bind1st(std::mem_fun_ref(&Bar::process), bar));
У нас for_each
там тоже есть - ура . У нас есть [begin; end)
диапазон, на котором мы хотим работать.
В принципе, алгоритм был намного более явным и поэтому предпочтительным по сравнению с любой рукописной реализацией. Но тогда ... Биндеры? Memfun? В основном C ++ interna о том, как заполучить функцию-член? Для моей задачи я не забочусь о них! Я также не хочу страдать от этого многословного, жуткого синтаксиса.
Теперь другая возможность:
for (std::vector<Foo>::const_iterator it = vec.begin(); it != vec.end(); ++it)
{
bar.process(*it);
}
Конечно, это обычный шаблон для распознавания, но ... создание итераторов, зацикливание, увеличение, разыменование. Это тоже все, что меня не волнует , чтобы выполнить мою задачу.
Следует признать, что это выглядит waay лучше , чем первое решение (по крайней мере, контур тела является гибким и достаточно четко), но все же, это на самом деле не что большой. Мы будем использовать этот, если у нас не было лучшей возможности, но, возможно, у нас есть ...
Лучше?
Теперь вернемся к for_each
. Разве не было бы здорово буквально сказать for_each
и быть гибким в операции, которая должна быть выполнена тоже? К счастью, начиная с C ++ 0x лямбды, мы
for_each(v.begin(), v.end(), [&](const Foo& x) { bar.process(x); })
Теперь, когда мы нашли абстрактное, общее решение для многих связанных ситуаций, стоит отметить, что в данном конкретном случае существует абсолютный фаворит №1 :
foreach(const Foo& x, vec) bar.process(x);
Это действительно не может быть намного яснее, чем это. К счастью, в C ++ 0x get встроен похожий синтаксис !
map(bar.process, vec)
хотя карта для побочных эффектов не рекомендуется, и списочные выражения / выражения генератора рекомендуются над картой).