Namespaces
Variants

std::for_each

Von de.cppreference.net
 
 
Algorithmenbibliothek
Eingeschränkte Algorithmen und Algorithmen auf Bereichen (C++20)
Eingeschränkte Algorithmen, z. B. ranges::copy, ranges::sort, ...
Nicht modifizierende Sequenzoperationen    
Stapeloperationen
(C++17)
Suchoperationen
Modifizierende Sequenzoperationen
Kopieroperationen
(C++11)
(C++11)
Tauschoperationen
Transformationsoperationen
Generierungsoperationen
Entfernungsoperationen
Reihenfolgeändernde Operationen
(bis C++17)(C++11)
(C++20)(C++20)
Stichprobenoperationen
(C++17)

Sortier- und verwandte Operationen
Partitionierungsoperationen
(C++11)    

Sortieroperationen
Binäre Suchoperationen
(auf partitionierten Bereichen)
Mengenoperationen (auf sortierten Bereichen)
Mischoperationen (auf sortierten Bereichen)
Heap-Operationen
Minimum/Maximum-Operationen
(C++11)
(C++17)
Lexikografische Vergleichsoperationen
Permutationsoperationen


 
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.

1) f wird der Reihe nach ab first angewendet.

Wenn UnaryFunc nicht MoveConstructible ist, ist das Verhalten undefiniert.

(seit C++11)
2) f wird möglicherweise nicht der Reihe nach angewendet. Der Algorithmus wird gemäß policy ausgeführt.
Anders als andere parallele Algorithmen darf for_each keine beliebigen Kopien von Elementen aus dem Zielbereich erstellen.
Diese Überladung nimmt nur an der Überladungsauflösung teil, wenn der Wert des folgenden Ausdrucks true ist:

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

(bis C++20)

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

(seit C++20)
Wenn 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:

void fun(const Type &a);

Die Signatur muss kein const & enthalten.
Der Typ Type muss so sein, dass ein Objekt vom Typ InputIt dereferenziert und dann implizit in Type konvertiert werden kann.

​

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

1) f

Komplexität

Genau std::distance(first, last) Anwendungen von f.

Ausnahmen

2) Während des Ausführungsprozesses:
  • 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 Elemente
der durchlaufenen Sequenz ändern kann (for_each wird
als „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

wendet ein unäres Funktionsobjekt auf Elemente aus einem Bereich
an(Algorithmus-Funktionsobjekt)
wendet ein Funktionsobjekt auf die ersten N Elemente einer Sequenz an
(Funktionsschablone & Algorithmus-Funktionsobjekt)
wendet eine Funktion auf einen Bereich von Elementen an, speichert Ergebnisse in einem Zielbereich
(Funktionsschablone & Algorithmus-Funktionsobjekt)
Bereichs-for Schleife(C++11) führt Schleife über Bereich aus