std::ranges::for_each, std::ranges::for_each_result
| Definiert im Header <algorithm>
|
||
| Aufrufsignatur |
||
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) | (seit 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) | (seit 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) | (seit 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) | (seit C++26) |
| Hilfstypen |
||
template< class I, class F >
using for_each_result = ranges::in_fun_result<I, F>;
|
(5) | (seit C++20) |
Für die Definition von /*execution-policy*/ siehe diese Seite; für die Definition von /*sized-random-access-range*/ siehe diese Seite.
Wendet das gegebene aufrufbare Objekt f auf jedes Element (projiziert durch proj) im Zielbereich [first, last) oder r an. Wenn f ein Ergebnis zurückgibt, wird das Ergebnis ignoriert.
f wird der Reihe nach vom Anfang des Zielbereichs angewendet.f wird möglicherweise nicht der Reihe nach angewendet. Der Algorithmus wird gemäß policy ausgeführt.for_each nicht erlaubt, beliebige Kopien von Elementen aus dem Zielbereich zu erstellen.Die funktionsartigen Entitäten, die auf dieser Seite beschrieben werden, sind Algorithmus-Funktionsobjekte (informell als Niebloids bekannt), das heißt:
- Explizite Vorlagenargumentlisten können beim Aufruf keiner von ihnen angegeben werden.
- Keine von ihnen sind für argumentabhängige Namenssuche sichtbar.
- Wenn eine von ihnen durch normale unqualifizierte Namenssuche als Name links vom Funktionsaufrufoperator gefunden wird, wird argumentabhängige Namenssuche unterdrückt.
Parameter
| first, last | - | das Paar von Iteratoren, das den Ziel-bereich |
| definiert | - | der Zielbereich |
| f | - | das aufrufbare Objekt, das auf die (projizierten) Elemente angewendet werden soll |
| proj | - | die Projektion, die auf die Elemente angewendet werden soll |
| policy | - | die zu verwendende Ausführungsrichtlinie |
Rückgabewert
{last, std::move(f)}{ranges::next(ranges::begin(r), ranges::end(r)), std::move(f)} wenn R das Konzept forward_range modelliert, andernfalls (seit C++26){ranges::end(r), std::move(f)}lastranges::next(ranges::begin(r), ranges::end(r)) wenn R das Konzept forward_range modelliert, andernfalls (seit C++26)ranges::end(r)Komplexität
ranges::distance(first, last) Anwendungen von f und proj.ranges::distance(r) Anwendungen von f und proj.Ausnahmen
- Wenn die für die Parallelisierung erforderlichen temporären Speicherressourcen nicht verfügbar sind, wird std::bad_alloc ausgelöst.
- Wenn während des Zugriffs auf Objekte über ein Algorithmusargument eine nicht abgefangene Ausnahme ausgelöst wird, wird das Verhalten durch die Ausführungsrichtlinie bestimmt (für Standardrichtlinien wird std::terminate aufgerufen).
Hinweise
Wenn die Projektion eine veränderliche Referenz zurückgibt, kann f die Elemente im Zielbereich verändern.
Für die Überladungen (1,2) kann f ein zustandsbehaftetes aufrufbares Objekt sein. Das aufrufbare Objekt im Rückgabewert kann als Endzustand der Stapeloperation betrachtet werden.
Für die Überladungen (3,4) können mehrere Kopien von f erstellt werden, um parallele Aufrufe durchzuführen. Der Rückgabewert enthält kein aufrufbares Objekt, da Parallelisierung oft keine effiziente Zustandsakkumulation erlaubt.
Mögliche Implementierung
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;
|
Beispiel
Das folgende Beispiel verwendet einen Lambda-Ausdruck, um alle Elemente eines Vektors zu inkrementieren, und dann eine überladene operator() in einem aufrufbaren Objekt, um deren Summe zu berechnen. Beachten Sie, dass zur Berechnung der Summe der dedizierte Algorithmus std::accumulate empfohlen wird.
#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');
}
Ausgabe:
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
Siehe auch
| wendet ein unäres Funktionsobjekt auf Elemente aus einem Bereich an (Funktionsvorlage) | |
(C++20) |
wendet ein Funktionsobjekt auf die ersten N Elemente einer Sequenz an (Algorithmus-Funktionsobjekt) |
(C++20) |
wendet eine Funktion auf einen Bereich von Elementen an (Algorithmus-Funktionsobjekt) |
bereichsbasierte for for-Schleife
|
(C++11) |