Namespaces
Variants

std::for_each

Issu de fr.cppreference.net
 
 
Bibliothèque d'algorithmes
Algorithmes contraints et algorithmes sur plages (C++20)
Algorithmes contraints, ex. ranges::copy, ranges::sort, ...
Opérations de séquence non modifiantes    
Opérations par lots
(C++17)
Opérations de recherche
Opérations de séquence modifiantes
Opérations de copie
(C++11)
(C++11)
Opérations d'échange
Opérations de transformation
Opérations de génération
Opérations de suppression
Opérations de changement d'ordre
(jusqu'à C++17)(C++11)
(C++20)(C++20)
Opérations d'échantillonnage
(C++17)

Tri et opérations associées
Opérations de partitionnement
(C++11)    

Opérations de tri
Opérations de recherche binaire
(sur plages partitionnées)
Opérations d'ensemble (sur plages triées)
Opérations de fusion (sur plages triées)
Opérations de tas
Opérations minimum/maximum
(C++11)
(C++17)
Opérations de comparaison lexicographique
Opérations de permutation


 
Défini dans l'en-tête <algorithm>
template< class InputIt, class UnaryFunc >
UnaryFunc for_each( InputIt first, InputIt last, UnaryFunc f );
(1) (constexpr depuis C++20)
template< class ExecutionPolicy, class ForwardIt, class UnaryFunc >
void for_each( ExecutionPolicy&& policy,
               ForwardIt first, ForwardIt last, UnaryFunc f );
(2) (depuis C++17)

Applique l'objet invocable donné f à chaque élément de la plage cible [firstlast). Si f retourne un résultat, le résultat est ignoré.

1) f est appliqué dans l'ordre en commençant par first.

Si UnaryFunc n'est pas MoveConstructible, le comportement est indéfini.

(depuis C++11)
2) f pourrait ne pas être appliqué dans l'ordre. L'algorithme est exécuté selon policy.
Contrairement aux autres algorithmes parallèles, for_each n'est pas autorisé à faire des copies arbitraires des éléments de la plage cible.
Cette surcharge participe à la résolution de surcharge seulement si la valeur de l'expression suivante est true :

std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>

(jusqu'à C++20)

std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>

(depuis C++20)
Si UnaryFunc n'est pas CopyConstructible, le comportement est indéfini.

Paramètres

first, last - la paire d'itérateurs définissant la plage
ciblef - objet fonction, à appliquer aux éléments

La signature de la fonction doit être équivalente à la suivante :

void fun(const Type &a);

La signature n'a pas besoin d'avoir const &.
Le type Type doit être tel qu'un objet de type InputIt peut être déréférencé puis implicitement converti en Type.

policy - la politique d'exécution à utiliser
Exigences de type
-
InputIt doit satisfaire les exigences de LegacyInputIterator.
-
ForwardIt doit satisfaire les exigences de LegacyForwardIterator.

Valeur de retour

1) f

Complexité

Exactement std::distance(first, last) applications de f.

Exceptions

2) Pendant le processus d'exécution :
  • Si les ressources mémoire temporaires nécessaires à la parallélisation ne sont pas disponibles, std::bad_alloc est lancée.
  • Si une exception non interceptée est levée lors de l'accès aux objets via un argument d'algorithme, le comportement est déterminé par la politique d'exécution (pour les politiques standard, std::terminate est invoquée).

Notes

Si le type d'itérateur (InputIt/ForwardIt) est mutable, f peut modifier les éléments de la plage cible.

Pour la surcharge (1), f peut être un objet invocable avec état. La valeur de retour peut être considérée comme l'état final de l'opération par lots.

Pour la surcharge (2), plusieurs copies de f peuvent être créées pour effectuer l'invocation parallèle. Aucune valeur n'est retournée car la parallélisation ne permet souvent pas une accumulation d'état efficace.

Implémentation possible

Voir aussi les implémentations dans libstdc++, libc++ et MSVC stdlib.

template<class InputIt, class UnaryFunc>
constexpr UnaryFunc for_each(InputIt first, InputIt last, UnaryFunc f)
{
    for (; first != last; ++first)
        f(*first);
    
    return f; // implicit move since C++11
}

Exemple

L'exemple suivant utilise une expression lambda pour incrémenter tous les éléments d'un vecteur, puis utilise un operator() surchargé dans un objet invocable pour calculer leur somme. Notez que pour calculer la somme, il est recommandé d'utiliser l'algorithme dédié std::accumulate.

#include <algorithm>
#include <iostream>
#include <vector>
 
int main()
{
    std::vector<int> v{3, -4, 2, -8, 15, 267};
    
    auto print = [](const int& n) { std::cout << n << ' '; };
    
    std::cout << "before:\t";
    std::for_each(v.cbegin(), v.cend(), print);
    std::cout << '\n';
    
    // increment elements in-place
    std::for_each(v.begin(), v.end(), [](int &n) { n++; });
    
    std::cout << "after:\t";
    std::for_each(v.cbegin(), v.cend(), print);
    std::cout << '\n';
    
    struct Sum
    {
        void operator()(int n) { sum += n; }
        int sum {0};
    };
    
    // invoke Sum::operator() for each element
    Sum s = std::for_each(v.cbegin(), v.cend(), Sum());    
    std::cout << "sum:\t" << s.sum << '\n';
}

Sortie :

before:	3 -4 2 -8 15 267 
after:	4 -3 3 -7 16 268 
sum:	281

Rapports de défauts

Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.

DR Appliqué à Comportement tel que publié Comportement correct
LWG 475 C++98 il n'était pas clair si f peut modifier les éléments
de la séquence parcourue (for_each est
classifié comme « opérations de séquence non modifiantes »)
clarifié (autorisé si le
type d'itérateur est mutable)
LWG 2747 C++11 la surcharge (1) retournait std::move(f) retourne f (ce qui déplace implicitement)

Voir aussi

applique un objet fonction unaire aux éléments d'une plage
(objet fonction d'algorithme)
applique un objet fonction aux N premiers éléments d'une séquence
(modèle de fonction & objet fonction d'algorithme)
applique une fonction à une plage d'éléments, stockant les résultats dans une plage de destination
(modèle de fonction & objet fonction d'algorithme)
boucle forfor basée sur une plage(C++11) exécute une boucle sur une plage