std::ranges::for_each, std::ranges::for_each_result
| Definiert in Header <algorithm> |
||
| Aufruf-Signatur |
||
| template< std::input_iterator I, std::sentinel_for<I> S, class Proj = std::identity, std::indirectly_unary_invocable<std::projected<I, Proj>> Fun > |
(1) | (seit C++20) |
| template< ranges::input_range R, class Proj = std::identity, std::indirectly_unary_invocable< |
(2) | (seit C++20) |
| Hilfstypen |
||
| template< class I, class F > using for_each_result = ranges::in_fun_result<I, F>; |
(3) | (seit C++20) |
[first, last) an, wobei die Werte projiziert werden. Die Anwendung erfolgt in Reihenfolge.Für beide Überladungen gilt: Wenn der Iteratortyp veränderbar ist, darf f die Elemente des Bereichs über den dereferenzierten Iterator ändern. Wenn f ein Ergebnis zurückgibt, wird dieses ignoriert.
Die auf dieser Seite beschriebenen funktionsähnlichen Entitäten sind Algorithmus-Funktionsobjekte (informell als niebloids bekannt), d.h.
- Können explizite Template-Argumentlisten bei keinem von ihnen angegeben werden.
- Keiner von ihnen ist für Argument-abhängige Suche sichtbar.
- Wenn einer von ihnen durch normale unqualifizierte Suche als Name links vom Funktionsaufrufoperator gefunden wird, wird die Argument-abhängige Suche unterdrückt.
Inhalt |
[edit] Parameter
| first, last | - | Das Iterator-Sentinel-Paar, das den Bereich der anzuwendenden Funktionselemente definiert |
| r | - | Der Bereich der anzuwendenden Funktionselemente |
| f | - | Die anzuwendende Funktion auf den projizierten Bereich |
| proj | - | Projektion, die auf die Elemente angewendet wird |
[edit] Rückgabewert
{std::ranges::next(std::move(first), last), std::move(f)}
[edit] Komplexität
Genau last - first Anwendungen von f und proj.
[edit] 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)); } }; inline constexpr for_each_fn for_each; |
[edit] Beispiel
Das folgende Beispiel verwendet einen Lambda-Ausdruck, um alle Elemente eines Vektors zu inkrementieren, und verwendet dann einen überladenen operator() in einem Funktor, um deren Summe zu berechnen. Beachten Sie, dass für die Berechnung der Summe die Verwendung des dedizierten 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() { std::vector<int> nums {3, 4, 2, 8, 15, 267}; auto print = [](const auto& n) { std::cout << ' ' << n; }; namespace ranges = std::ranges; 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
[edit] Siehe auch
Bereichs-for-Schleife(C++11) |
führt Schleife über einen Bereich aus |
| (C++20) |
Wendet eine Funktion auf einen Elementbereich an (Algorithmus-Funktionsobjekt) |
| (C++20) |
Wendet ein Funktionsobjekt auf die ersten N Elemente einer Sequenz an (Algorithmus-Funktionsobjekt) |
| wendet ein unäres Funktionsobjekt auf Elemente aus einem Bereich an (Funktion-Template) |