std::ranges::for_each, std::ranges::for_each_result
| Défini dans l'en-tête <algorithm>
|
||
| Signature d'appel |
||
template< std::input_iterator I, std::sentinel_for<I> S,
class Proj = std::identity,
std::indirectly_unary_invocable<std::projected<I, Proj>> Fun >
constexpr for_each_result<I, Fun>
for_each( I first, S last, Fun f, Proj proj = {} );
|
(1) | (depuis C++20) |
template< ranges::input_range R, class Proj = std::identity,
std::indirectly_unary_invocable
<std::projected<ranges::iterator_t<R>, Proj>> Fun >
constexpr for_each_result<ranges::borrowed_iterator_t<R>, Fun>
for_each( R&& r, Fun f, Proj proj = {} );
|
(2) | (depuis C++20) |
template< /*execution-policy*/ Ep, std::random_access_iterator I,
std::sized_sentinel_for<I> S, class Proj = std::identity,
std::indirectly_unary_invocable<std::projected<I, Proj>> Fun >
I for_each( Ep&& policy, I first, S last, Fun f, Proj proj = {} );
|
(3) | (depuis C++26) |
template< /*execution-policy*/ Ep,
/*sized-random-access-range*/ R, class Proj = std::identity,
std::indirectly_unary_invocable
<std::projected<ranges::iterator_t<R>, Proj>> Fun >
ranges::borrowed_iterator_t<R>
for_each( Ep&& policy, R&& r, Fun f, Proj proj = {} );
|
(4) | (depuis C++26) |
| Types d'assistance |
||
template< class I, class F >
using for_each_result = ranges::in_fun_result<I, F>;
|
(5) | (depuis C++20) |
Pour la définition de /*execution-policy*/, voir cette page ; pour la définition de /*sized-random-access-range*/, voir cette page.
Applique l'objet invocable donné f à chaque élément (projeté par proj) dans la plage cible [first, last) ou r. Si f retourne un résultat, le résultat est ignoré.
f est appliqué dans l'ordre depuis le début de la plage cible.f peut ne pas être appliqué dans l'ordre. L'algorithme est exécuté selon policy.for_each n'est pas autorisé à faire des copies arbitraires d'éléments de la plage cible.Les entités de type fonction décrites sur cette page sont des objets fonction d'algorithme (informellement appelés niebloids), c'est-à-dire :
- Les listes explicites d'arguments de modèle ne peuvent pas être spécifiées lors de l'appel à l'une d'elles.
- Aucune d'elles n'est visible par recherche dépendante des arguments.
- Lorsque l'une d'elles est trouvée par recherche non qualifiée normale comme le nom à gauche de l'opérateur d'appel de fonction, la recherche dépendante des arguments est inhibée.
Paramètres
| first, last | - | la cible plage |
| r | - | la plage cible |
| f | - | l'objet invocable à appliquer aux éléments (projetés) |
| proj | - | la projection à appliquer aux éléments |
| policy | - | la politique d'exécution à utiliser |
Valeur de retour
{last, std::move(f)}{ranges::next(ranges::begin(r), ranges::end(r)), std::move(f)} si R modélise forward_range, sinon (depuis C++26){ranges::end(r), std::move(f)}lastranges::next(ranges::begin(r), ranges::end(r)) si R modélise forward_range, sinon (depuis C++26)ranges::end(r)Complexité
ranges::distance(first, last) applications de f et proj.ranges::distance(r) applications de f et proj.Exceptions
- Si les ressources mémoire temporaires nécessaires à la parallélisation ne sont pas disponibles, std::bad_alloc est levée.
- Si une exception non capturé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 la projection retourne une référence mutable, f peut modifier les éléments de la plage cible.
Pour les surcharges (1,2), f peut être un objet invocable avec état. L'objet invocable dans la valeur de retour peut être considéré comme l'état final de l'opération par lots.
Pour les surcharges (3,4), plusieurs copies de f peuvent être créées pour effectuer une invocation parallèle. La valeur de retour ne contient pas d'objet invocable car la parallélisation ne permet souvent pas une accumulation d'état efficace.
Implémentation possible
struct for_each_fn
{
template<std::input_iterator I, std::sentinel_for<I> S, class Proj = std::identity,
std::indirectly_unary_invocable<std::projected<I, Proj>> Fun>
constexpr ranges::for_each_result<I, Fun>
operator()(I first, S last, Fun f, Proj proj = {}) const
{
for (; first != last; ++first)
std::invoke(f, std::invoke(proj, *first));
return {std::move(first), std::move(f)};
}
template<ranges::input_range R, class Proj = std::identity,
std::indirectly_unary_invocable
<std::projected<ranges::iterator_t<R>, Proj>> Fun>
constexpr ranges::for_each_result<ranges::borrowed_iterator_t<R>, Fun>
operator()(R&& r, Fun f, Proj proj = {}) const
{
return (*this)(ranges::begin(r), ranges::end(r), std::move(f), std::ref(proj));
}
template<ranges::forward_range R, class Proj = std::identity,
std::indirectly_unary_invocable
<std::projected<ranges::iterator_t<R>, Proj>> Fun>
constexpr ranges::for_each_result<ranges::borrowed_iterator_t<R>, Fun>
operator()(R&& r, Fun f, Proj proj = {}) const
{
return (*this)(ranges::begin(r),
ranges::next(ranges::begin(r), ranges::end(r)),
std::move(f), std::ref(proj));
}
};
inline constexpr for_each_fn for_each;
|
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 <cassert>
#include <iostream>
#include <string>
#include <utility>
#include <vector>
struct Sum
{
void operator()(int n) { sum += n; }
int sum {0};
};
int main()
{
namespace ranges = std::ranges;
std::vector<int> nums {3, 4, 2, 8, 15, 267};
auto print = [](const auto& n) { std::cout << ' ' << n; };
std::cout << "before:";
ranges::for_each(std::as_const(nums), print);
print('\n');
ranges::for_each(nums, [](int& n) { ++n; });
// calls Sum::operator() for each number
auto [i, s] = ranges::for_each(nums.begin(), nums.end(), Sum());
assert(i == nums.end());
std::cout << "after: ";
ranges::for_each(nums.cbegin(), nums.cend(), print);
std::cout << "\n" "sum: " << s.sum << '\n';
using pair = std::pair<int, std::string>;
std::vector<pair> pairs {{1,"one"}, {2,"two"}, {3,"tree"}};
std::cout << "project the pair::first: ";
ranges::for_each(pairs, print, [](const pair& p) { return p.first; });
std::cout << "\n" "project the pair::second:";
ranges::for_each(pairs, print, &pair::second);
print('\n');
}
Sortie :
before: 3 4 2 8 15 267
after: 4 5 3 9 16 268
sum: 305
project the pair::first: 1 2 3
project the pair::second: one two tree
Voir aussi
| applique un foncteur unaire aux éléments d'une plage (modèle de fonction) | |
(C++20) |
applique un foncteur aux N premiers éléments d'une séquence (foncteur d'algorithme) |
(C++20) |
applique une fonction à une plage d'éléments (foncteur d'algorithme) |
plage-for boucle(C++11)
|
exécute une boucle sur une plage |