Я собираюсь пойти против этого и утверждать, что использование алгоритмов STL с функторами значительно упрощает понимание и сопровождение кода, но вы должны делать это правильно. Вы должны уделять больше внимания удобочитаемости и четкости. В частности, вы должны получить правильное наименование. Но когда вы это сделаете, вы можете получить более чистый и ясный код, и парадигма перейдет на более мощные методы кодирования.
Давайте рассмотрим пример. Здесь у нас есть группа детей, и мы хотим установить для их «Foo Count» какое-то значение. Стандартный цикл for, итераторный подход:
for (vector<Child>::iterator iter = children.begin();
iter != children.end();
++iter)
{
iter->setFooCount(n);
}
Что, да, это довольно ясно, и определенно не плохой код. Вы можете понять это, просто немного посмотрев на это. Но посмотрите, что мы можем сделать с соответствующим функтором:
for_each(children.begin(), children.end(), SetFooCount(n));
Ух ты, это говорит именно то, что нам нужно. Вам не нужно это выяснять; Вы сразу же знаете, что он устанавливает «количество Foo» для каждого ребенка. (Было бы еще яснее, если бы нам не понадобилась ерунда .begin () / .end (), но у вас не может быть всего, и они не советовались со мной при создании STL.)
Конечно, вам нужно определить этот магический функтор, SetFooCount
, но его определение довольно стандартно:
class SetFooCount
{
public:
SetFooCount(int n) : fooCount(n) {}
void operator () (Child& child)
{
child.setFooCount(fooCount);
}
private:
int fooCount;
};
В целом это больше кода, и вам нужно посмотреть в другом месте, чтобы точно узнать, что делает SetFooCount
. Но поскольку мы назвали его правильно, в 99% случаев нам не нужно искать код для SetFooCount
. Мы предполагаем, что он делает то, что говорит, и нам нужно только взглянуть на строку for_each
.
Что мне действительно нравится, так это то, что использование алгоритмов приводит к смене парадигмы. Вместо того, чтобы думать о списке как о коллекции объектов, и делать что-то с каждым элементом списка, вы думаете о списке как о первоклассной сущности и работаете непосредственно с самим списком. Цикл for выполняет итерацию по списку, вызывая функцию-член для каждого элемента для установки счетчика Foo. Вместо этого я делаю одну команду, которая устанавливает Foo Count каждого элемента в списке. Это тонко, но когда вы смотрите на лес, а не на деревья, вы получаете больше силы.
Поэтому, немного подумав и осторожно назвав, мы можем использовать алгоритмы STL для создания более чистого и ясного кода и начать думать на менее детальном уровне.