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,
|
(2) | (seit C++17) |
Wendet das gegebene unäre
Funktionsobjekt
f
auf das Ergebnis der Dereferenzierung jedes
Iterators
im
Bereich
[
first
,
last
)
an. Falls
f
ein Ergebnis zurückgibt, wird das Ergebnis ignoriert.
|
Falls
|
(since C++11) |
|
std:: is_execution_policy_v < std:: decay_t < ExecutionPolicy >> ist true . |
(bis C++20) |
|
std:: is_execution_policy_v < std:: remove_cvref_t < ExecutionPolicy >> ist true . |
(seit C++20) |
Wenn der Iteratortyp (
InputIt
/
ForwardIt
) mutable ist,
f
kann die Elemente des
Bereichs
durch den dereferenzierten Iterator modifizieren.
Im Gegensatz zu den anderen parallelen Algorithmen ist es
for_each
nicht erlaubt, Kopien der Elemente in der Sequenz zu erstellen, selbst wenn sie
TriviallyCopyable
sind.
Inhaltsverzeichnis |
Parameter
| first, last | - | das Paar von Iteratoren, das den Bereich der Elemente definiert, auf die das Funktionsobjekt angewendet wird |
| policy | - | die zu verwendende Ausführungsrichtlinie |
| f | - |
Funktionsobjekt, das auf das Ergebnis der Dereferenzierung jedes Iterators im
Bereich
[
first
,
last
)
Die Signatur der Funktion sollte äquivalent zu Folgendem sein: void fun ( const Type & a ) ;
Die Signatur muss nicht
const
&
enthalten.
|
| Typanforderungen | ||
-
InputIt
muss die Anforderungen von
LegacyInputIterator
erfüllen.
|
||
-
ForwardIt
muss die Anforderungen von
LegacyForwardIterator
erfüllen.
|
||
Rückgabewert
Komplexität
Genau std:: distance ( first, last ) Anwendungen von f .
Ausnahmen
Die Überladung mit einem Template-Parameter namens
ExecutionPolicy
meldet Fehler wie folgt:
-
Wenn die Ausführung einer als Teil des Algorithmus aufgerufenen Funktion eine Exception wirft und
ExecutionPolicyeiner der Standard-Policies ist, wird std::terminate aufgerufen. Für jede andereExecutionPolicyist das Verhalten implementierungsdefiniert. - Wenn der Algorithmus keinen Speicher allozieren kann, wird std::bad_alloc geworfen.
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; // implizites Move seit C++11 } |
Hinweise
Für Überladung ( 1 ) kann f ein zustandsbehaftetes Funktionsobjekt sein. Der Rückgabewert kann als Endzustand des Stapelvorgangs betrachtet werden.
Für Überladung ( 2 ) können mehrere Kopien von f erstellt werden, um parallelen Aufruf durchzuführen. Es wird kein Wert zurückgegeben, da Parallelisierung häufig keine effiziente Zustandsakkumulation erlaubt.
Beispiel
Das folgende Beispiel verwendet einen
Lambda-Ausdruck
, um alle Elemente eines Vektors zu inkrementieren, und verwendet dann einen überladenen
operator()
in einem Funktionsobjekt (auch bekannt als "Funktor"), um deren Summe zu berechnen. Beachten Sie, dass zur Berechnung der Summe der spezielle 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'; // Elemente direkt inkrementieren 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}; }; // Sum::operator() für jedes Element aufrufen 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 | Korrektes Verhalten |
|---|---|---|---|
| LWG 475 | C++98 |
es war unklar, ob
f
die Elemente der Sequenz
modifizieren darf, über die iteriert wird (
for_each
ist
als "nicht-modifizierende Sequenzoperationen" klassifiziert) |
klargestellt (erlaubt, wenn der
Iteratortyp mutable ist) |
| LWG 2747 | C++11 | Überladung ( 1 ) gab std :: move ( f ) zurück | gibt f zurück (was implizit bewegt) |
Siehe auch
|
wendet eine Funktion auf einen Elementbereich an und speichert die Ergebnisse in einem Zielbereich
(Funktions-Template) |
|
|
(C++17)
|
wendet ein Funktionsobjekt auf die ersten N Elemente einer Sequenz an
(Funktions-Template) |
|
(C++20)
|
wendet ein unäres
Funktionsobjekt
auf Elemente aus einem
Bereich
an
(Algorithmus-Funktionsobjekt) |
|
(C++20)
|
wendet ein Funktionsobjekt auf die ersten N Elemente einer Sequenz an
(Algorithmus-Funktionsobjekt) |
Range-
for
-Schleife
(C++11)
|
führt Schleife über Bereich aus |