2010-12-15 114 views
1

Pour l'instant, je cours une boucle for où je fais un appel sur chaque élément dans un conteneur STL, semblable à ce qui suit. Je regarde l'algorithme STL for_each car il semble correspondre à mes besoins. Je me demandais si, étant donné l'utilisation d'un deuxième paramètre d'entrée à la fonction appliquée au conteneur, il est possible de refactoriser ceci pour utiliser un algorithme STL standard sans utiliser de variables membres ou d'autres failles?Est-il possible d'utiliser l'algorithme STL for_each en utilisant une fonction avec des paramètres d'entrée indépendants?

Répondre

4

Les différents std::bind1st/std::bind2nd et la bibliothèque Boost.bind ont été créées pour résoudre votre problème (qui est commun à presque tous ceux qui ont utilisé les algorithmes STL), mais souvent ils semblent juste une solution au lieu d'une solution.

Heureusement, avec le prochain standard C++, l'ajout tant attendu de lambda functions devrait résoudre définitivement le problème. Cependant, notez que, puisque std::for_each appelle le foncteur passant l'itérateur déréférencé (c'est-à-dire la valeur réelle considérée), votre fonction AddToUpdate ne doit pas accepter l'itérateur, mais la valeur.

Dans ce cas, ce serait quelque chose comme ceci:

Update update; 
std::foreach(container.begin(); container.end(); [ & update](TypeOfTheValue Value) { 
    AddToUpdate(Value, update); 
}); 
+0

Une autre option consiste à écrire un foncteur pour faire le travail. Cela permettrait d'obtenir un comportement similaire à la version lambda, mais sans nécessiter le support du compilateur pour C++ 0x. – jalf

+1

Tout le point de liaison n'est pas d'écrire des foncteurs. –

4

Vous voulez utiliser std::bind2nd()-http://www.cplusplus.com/reference/std/functional/bind2nd/

Fondamentalement, il retourne un objet de fonction unaire de fonction avec 2 arguments, où le second argument est fixé.

Voici comment votre code devrait ressembler à for_each et bind2nd:

Update update; 
for_each(container.begin(), container.end(), bind2nd(ptr_fun(AddToUpdate), update)); 

Modifier. Comme Matteo a remarqué que le premier argument de AddToUpdate doit être le type de valeur dans le conteneur, pas un itérateur.

+1

Mais cela ne fonctionne que sur les foncteurs provenant de 'std :: binary_function', et non sur les fonctions. –

+2

@Konrad qui pourrait être résolu avec 'std :: ptr_fun'. –

+1

À droite, modifié. Je suis habitué à 'boost :: bind', donc j'ai oublié combien la douleur était pure STL. –