私はここで逆行し、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 Count」を設定していることはすぐにわかります。(.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 カウントを設定する 1 つのコマンドを実行しています。ささやかですが、木ではなく森を見ると、より力が湧いてきます。
したがって、少し考えて慎重に命名することで、STL アルゴリズムを使用して、よりクリーンで明確なコードを作成し、より細かいレベルで考え始めることができます。