Namensräume
Varianten
Aktionen

std::for_each

Von cppreference.com
< cpp‎ | algorithm
 
 
Algorithmenbibliothek
Beschränkte Algorithmen und Algorithmen für Bereiche (C++20)
Beschränkte Algorithmen, z.B. ranges::copy, ranges::sort, ...
Ausführungsrichtlinien (C++17)
Nicht-modifizierende Sequenzoperationen
Stapeloperationen
for_each
(C++17)
Suchoperationen
(C++11)                (C++11)(C++11)

Modifizierende Sequenzoperationen
Kopieroperationen
(C++11)
(C++11)
Tauschoperationen
Transformationsoperationen
Generierungsoperationen
Entfernungsoperationen
Ordnungsändernde Operationen
(bis C++17)(C++11)
(C++20)(C++20)
Stichprobenoperationen
(C++17)

Sortier- und verwandte Operationen
Partitionierungsoperationen
Sortieroperationen
Binäre Suchoperationen
(auf partitionierten Bereichen)
Mengenoperationen (auf sortierten Bereichen)
Zusammenführungsoperationen (auf sortierten Bereichen)
Heapoperationen
Minimum/Maximum-Operationen
(C++11)
(C++17)
Lexikographische Vergleichsoperationen
Permutationsoperationen
C-Bibliothek
Numerische Operationen
Operationen auf uninitialisiertem Speicher
 
Definiert in 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 unäre Funktionsobjekt f auf das Ergebnis der Dereferenzierung jedes Iterators im Bereich [firstlast) an. Wenn f ein Ergebnis zurückgibt, wird dieses ignoriert.

1) f wird in der Reihenfolge ab first angewendet.

Wenn UnaryFunc nicht MoveConstructible ist, ist das Verhalten undefiniert.

(seit C++11)
2) f wird möglicherweise nicht in der Reihenfolge angewendet. Der Algorithmus wird gemäß policy ausgeführt.
Diese Überladung nimmt an der Überladungsauflösung teil, nur wenn alle folgenden Bedingungen erfüllt sind

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 UnaryFunc nicht CopyConstructible ist, ist das Verhalten undefiniert.

Wenn der Iterator-Typ (InputIt/ForwardIt) veränderbar ist, darf f die Elemente des Bereichs über den dereferenzierten Iterator modifizieren.

Im Gegensatz zu den anderen parallelen Algorithmen darf for_each keine Kopien der Elemente der Sequenz erstellen, auch wenn diese TriviallyCopyable sind.

Inhalt

[edit] Parameter

first, last - das Paar von Iteratoren, das den Bereich von Elementen definiert, auf die das Funktionsobjekt angewendet wird
policy - die Ausführungsrichtlinie, die verwendet werden soll
f - Funktionsobjekt, das auf das Ergebnis der Dereferenzierung jedes Iterators im Bereich [firstlast) angewendet wird

Die Signatur der Funktion sollte äquivalent zu folgender sein:

 void fun(const Type &a);

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

Typanforderungen
-
InputIt muss die Anforderungen von LegacyInputIterator erfüllen.
-
ForwardIt muss die Anforderungen von LegacyForwardIterator erfüllen.

[edit] Rückgabewert

1) f
2) (keiner)

[edit] Komplexität

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

[edit] Ausnahmen

Die Überladung mit einem Template-Parameter namens ExecutionPolicy meldet Fehler wie folgt

  • Wenn die Ausführung einer Funktion, die als Teil des Algorithmus aufgerufen wird, eine Ausnahme auslöst und ExecutionPolicy eine der Standardrichtlinien ist, wird std::terminate aufgerufen. Für jede andere ExecutionPolicy ist das Verhalten implementierungsabhängig.
  • Wenn dem Algorithmus der Speicher zur Neuzuweisung fehlt, wird std::bad_alloc ausgelöst.

[edit] 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
}

[edit] Anmerkungen

Für Überladung (1) kann f ein zustandsbehaftetes Funktionsobjekt sein. Der Rückgabewert kann als der finale Zustand des Batch-Vorgangs 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, da die Parallelisierung oft keine effiziente Zustandsakkumulation erlaubt.

[edit] Beispiel

Das folgende Beispiel verwendet einen Lambda-Ausdruck, um alle Elemente eines Vektors zu inkrementieren, und dann eine überladene operator() in einem Funktionsobjekt (auch "Funktor" genannt), um ihre Summe zu berechnen. Beachten Sie, dass zum Berechnen der Summe die Verwendung des dedizierten 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

[edit] Fehlerberichte

Die folgenden Verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.

DR angewendet auf Verhalten wie veröffentlicht Korrigiertes Verhalten
LWG 475 C++98 war unklar, ob f die Elemente
der durchlaufenen Sequenz ändern kann
(for_each ist als "nicht-modifizierende Sequenzoperationen" klassifiziert)
wurde klargestellt (erlaubt, wenn der
Iterator-Typ veränderbar ist)
LWG 2747 C++11 Überladung (1) gab std::move(f) zurück gibt f zurück (was implizit verschiebt)

[edit] Siehe auch

Wendet eine Funktion auf einen Elementbereich an und speichert die Ergebnisse in einem Zielbereich
(Funktionstempelat) [edit]
Wendet ein Funktionsobjekt auf die ersten N Elemente einer Sequenz an
(Funktionstempelat) [edit]
wendet ein unäres Funktionsobjekt auf Elemente aus einem Bereich an
(Algorithmus-Funktionsobjekt)[edit]
Wendet ein Funktionsobjekt auf die ersten N Elemente einer Sequenz an
(Algorithmus-Funktionsobjekt)[edit]
Bereichs-for-Schleife(C++11) führt Schleife über einen Bereich aus[bearbeiten]