Завжди використовуйте той варіант, який найкраще описує те, що ви маєте намір зробити. Це є
Для кожного елемента xв vec, робити bar.process(x).
Тепер розглянемо приклади:
std::for_each(vec.begin(), vec.end(),
std::bind1st(std::mem_fun_ref(&Bar::process), bar));
У нас for_eachтеж є - yippeh . У нас є [begin; end)асортимент, над яким ми хочемо оперувати.
В принципі, алгоритм був набагато більш чітким і, таким чином, кращим перед будь-якою рукописною реалізацією. Але тоді ... Біндери? Мемфун? В основному C ++ internans про те, як влаштувати функцію члена? Для мого завдання я їх не хвилюю ! Ні я не хочу страждати від цього багатослівного, моторошного синтаксису.
Тепер інша можливість:
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)хоча карта побічних ефектів не рекомендується перераховувати, а перелік розуміння / вирази генератора рекомендується проводити над картою).