std::for_each
| Definiert im Header <algorithm>
|
||
template< class InputIt, class UnaryFunc >
UnaryFunc for_each( InputIt first, InputIt last, UnaryFunc f );
|
(1) | (constexpr seit C++20) |
template< class ExecutionPolicy, class ForwardIt, class UnaryFunc >
void for_each( ExecutionPolicy&& policy,
ForwardIt first, ForwardIt last, UnaryFunc f );
|
(2) | (seit C++17) |
Wendet das gegebene aufrufbare Objekt f auf jedes Element im Zielbereich [first, last) an. Wenn f ein Ergebnis zurückgibt, wird das Ergebnis ignoriert.
f wird der Reihe nach ab first angewendet.
|
Wenn |
(seit C++11) |
f wird möglicherweise nicht der Reihe nach angewendet. Der Algorithmus wird gemäß policy ausgeführt.for_each keine beliebigen Kopien von Elementen aus dem Zielbereich erstellen.true ist:
|
|
(bis C++20) |
|
|
(seit C++20) |
UnaryFunc nicht CopyConstructible ist, ist das Verhalten undefiniert.Parameter
| first, last | - | das Iteratorpaar, das den Zielbereich |
| definiertf | - | Funktionsobjekt, das auf die Elemente angewendet werden soll Die Signatur der Funktion sollte der folgenden entsprechen:
Die Signatur muss kein |
| policy | - | die Ausführungsstrategie zur Verwendung |
| Typanforderungen | ||
-InputIt muss die Anforderungen von LegacyInputIterator erfüllen.
| ||
-ForwardIt muss die Anforderungen von LegacyForwardIterator erfüllen.
| ||
Rückgabewert
fKomplexität
Genau std::distance(first, last) Anwendungen von f.
Ausnahmen
- Wenn die für die Parallelisierung erforderlichen temporären Speicherressourcen nicht verfügbar sind, wird std::bad_alloc ausgelöst.
- Wenn eine nicht abgefangene Ausnahme beim Zugriff auf Objekte über ein Algorithmusargument ausgelöst wird, wird das Verhalten durch die Ausführungsstrategie bestimmt (für Standardstrategien wird std::terminate aufgerufen).
Anmerkungen
Wenn der Iteratortyp (InputIt/ForwardIt) mutable ist, kann f die Elemente im Zielbereich ändern.
Für Überladung (1) kann f ein zustandsbehaftetes aufrufbares Objekt sein. Der Rückgabewert kann als der endgültige Zustand der Stapeloperation betrachtet werden.
Für Überladung (2) können mehrere Kopien von f erstellt werden, um parallele Aufrufe durchzuführen. Es wird kein Wert zurückgegeben, weil Parallelisierung oft keine effiziente Zustandsakkumulation erlaubt.
Mögliche Implementierung
Siehe auch die Implementierungen in libstdc++, libc++ und 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
}
|
Beispiel
Das folgende Beispiel verwendet einen Lambda-Ausdruck, um alle Elemente eines Vektors zu inkrementieren, und verwendet dann einen überladenen operator() in einem aufrufbaren Objekt, um ihre Summe zu berechnen. Beachten Sie, dass zur Berechnung der Summe der dedizierte Algorithmus std::accumulate empfohlen wird.
#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';
}
Ausgabe:
before: 3 -4 2 -8 15 267
after: 4 -3 3 -7 16 268
sum: 281
Fehlerberichte
Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | Angewendet auf | Verhalten wie veröffentlicht | Richtiges Verhalten |
|---|---|---|---|
| LWG 475 | C++98 | Es war unklar, ob f die Elementeder durchlaufenen Sequenz ändern kann ( for_each wirdals „nicht modifizierende Sequenzoperationen“ klassifiziert) |
Klarstellung (erlaubt, wenn der Iteratortyp mutable ist) |
| LWG 2747 | C++11 | Überladung (1) gab std::move(f)
|
gibt f zurück (was implizit verschiebt)
|
Siehe auch
(C++20) |
wendet ein unäres Funktionsobjekt auf Elemente aus einem Bereich an(Algorithmus-Funktionsobjekt) |
(C++17) |
wendet ein Funktionsobjekt auf die ersten N Elemente einer Sequenz an (Funktionsschablone & Algorithmus-Funktionsobjekt) |
(C++20) |
|
| wendet eine Funktion auf einen Bereich von Elementen an, speichert Ergebnisse in einem Zielbereich (Funktionsschablone & Algorithmus-Funktionsobjekt) | |
(C++20) |
|
Bereichs-for Schleife(C++11)
|
führt Schleife über Bereich aus |