Au moins quatre bonnes raisons:
La séparation des préoccupations
Dans votre exemple particulier, le foncteur-fondé de l'approche a l'avantage de séparer la logique d'itération à partir de la moyenne-la logique de calcul. Vous pouvez ainsi utiliser votre foncteur dans d'autres situations (pensez à tous les autres algorithmes de la STL), et vous pouvez utiliser d'autres foncteurs avec for_each
.
Paramétrage
Vous pouvez paramétrer un foncteur plus facilement. Ainsi, par exemple, vous pourriez avoir un CalculateAverageOfPowers
foncteur qui prend la moyenne des carrés ou des cubes, etc. de vos données, qui serait rédigé ainsi:
class CalculateAverageOfPowers
{
public:
CalculateAverageOfPowers(float p) : acc(0), n(0), p(p) {}
void operator() (float x) { acc += pow(x, p); n++; }
float getAverage() const { return acc / n; }
private:
float acc;
int n;
float p;
};
Vous pouvez bien sûr faire la même chose avec une fonction traditionnelle, mais alors la rend difficile à utiliser avec des pointeurs de fonction, car il a un autre prototype CalculateAverage
.
Statefulness
Et comme les foncteurs peut être dynamique, vous pourriez faire quelque chose comme ceci:
CalculateAverage avg;
avg = std::for_each(dataA.begin(), dataA.end(), avg);
avg = std::for_each(dataB.begin(), dataB.end(), avg);
avg = std::for_each(dataC.begin(), dataC.end(), avg);
à la moyenne dans un certain nombre de différents jeux de données.
Notez que presque tous les algorithmes de la STL/conteneurs qui acceptent les foncteurs leur demander d'être "pur" des prédicats, c'est à dire pas de changement observable dans l'état au fil du temps. for_each
est un cas particulier à cet égard (voir, par exemple, Efficace Bibliothèque C++ Standard - for_each vs transformer).
Performance
Foncteurs peuvent souvent être incorporé par le compilateur (le TSL est un tas de modèles, après tout). Alors que le même est théoriquement vrai, des fonctions, des compilateurs généralement ne inline par l'intermédiaire d'un pointeur de fonction. Le canoncial exemple est de comparer std::sort
vs qsort
; la version STL est souvent de 5 à 10 fois plus rapide, en supposant que la comparaison prédicat lui-même est simple.
Résumé
Bien sûr, il est possible d'émuler les trois premières avec des fonctions traditionnelles et des pointeurs, mais il devient beaucoup plus simple avec des foncteurs.