std::ranges::fold_left
| Definiert in Header <algorithm> |
||
| Aufruf-Signatur |
||
| (1) | ||
template< std::input_iterator I, std::sentinel_for<I> S, class T, /* indirectly-binary-left-foldable */<T, I> F > |
(seit C++23) (bis C++26) |
|
| template< std::input_iterator I, std::sentinel_for<I> S, class T = std::iter_value_t<I>, |
(seit C++26) | |
| (2) | ||
| template< ranges::input_range R, class T, /* indirectly-binary-left-foldable */ |
(seit C++23) (bis C++26) |
|
| template< ranges::input_range R, class T = ranges::range_value_t<R>, /* indirectly-binary-left-foldable */ |
(seit C++26) | |
| Hilfskonzepte |
||
| template< class F, class T, class I > concept /* indirectly-binary-left-foldable */ = /* see description */; |
(3) | (nur Exposition*) |
Links (higher-order function) [Fold (higher-order function)] die Elemente des gegebenen Bereichs, d. h. gibt das Ergebnis der Auswertung des Kettenausdrucks zurückf(f(f(f(init, x1), x2), ...), xn), wobei x1, x2, ..., xn Elemente des Bereichs sind.
Informell verhält sich ranges::fold_left wie die Überladung von std::accumulate, die ein binäres Prädikat akzeptiert.
Das Verhalten ist undefiniert, wenn [first, last) kein gültiger Bereich ist.
[first, last). Äquivalent zu return ranges::fold_left_with_iter(std::move(first), last, std::move(init), f).value.| Hilfskonzepte |
||
| template< class F, class T, class I, class U > concept /*indirectly-binary-left-foldable-impl*/ = |
(3A) | (nur Exposition*) |
| template< class F, class T, class I > concept /*indirectly-binary-left-foldable*/ = |
(3B) | (nur Exposition*) |
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 zu faltenden Elemente definiert |
| r | - | der Bereich der zu faltenden Elemente |
| init | - | der Anfangswert der Faltung |
| f | - | das binäre Funktions-Objekt |
[edit] Rückgabewert
Ein Objekt vom Typ U, das das Ergebnis der linken Faltung des gegebenen Bereichs über f enthält, wobei U äquivalent zu std::decay_t<std::invoke_result_t<F&, T, std::iter_reference_t<I>>> ist.
Wenn der Bereich leer ist, wird U(std::move(init)) zurückgegeben.
[edit] Mögliche Implementierungen
struct fold_left_fn { template<std::input_iterator I, std::sentinel_for<I> S, class T = std::iter_value_t<I>, /* indirectly-binary-left-foldable */<T, I> F> constexpr auto operator()(I first, S last, T init, F f) const { using U = std::decay_t<std::invoke_result_t<F&, T, std::iter_reference_t<I>>>; if (first == last) return U(std::move(init)); U accum = std::invoke(f, std::move(init), *first); for (++first; first != last; ++first) accum = std::invoke(f, std::move(accum), *first); return std::move(accum); } template<ranges::input_range R, class T = ranges::range_value_t<R>, /* indirectly-binary-left-foldable */<T, ranges::iterator_t<R>> F> constexpr auto operator()(R&& r, T init, F f) const { return (*this)(ranges::begin(r), ranges::end(r), std::move(init), std::ref(f)); } }; inline constexpr fold_left_fn fold_left; |
[edit] Komplexität
Genau ranges::distance(first, last) Anwendungen des Funktions-Objekts f.
[edit] Anmerkungen
Die folgende Tabelle vergleicht alle eingeschränkten Faltungsalgorithmen
| Faltungs-Funktionstemplate | Beginnt von | Anfangswert | Rückgabetyp |
|---|---|---|---|
| ranges::fold_left | left | init | U |
| ranges::fold_left_first | left | erstes Element | std::optional<U> |
| ranges::fold_right | right | init | U |
| ranges::fold_right_last | right | letztes Element | std::optional<U> |
| ranges::fold_left_with_iter | left | init |
(1) ranges::in_value_result<I, U> (2) ranges::in_value_result<BR, U>, wobei BR ranges::borrowed_iterator_t<R> ist |
| ranges::fold_left_first_with_iter | left | erstes Element |
(1) ranges::in_value_result<I, std::optional<U>> (2) ranges::in_value_result<BR, std::optional<U>> wobei BR ranges::borrowed_iterator_t<R> ist |
| Feature-Test-Makro | Wert | Std | Feature |
|---|---|---|---|
__cpp_lib_ranges_fold |
202207L |
(C++23) | std::ranges Fold-Algorithmen |
__cpp_lib_algorithm_default_value_type |
202403L |
(C++26) | Listeninitialisierung für Algorithmen (1,2) |
[edit] Beispiel
#include <algorithm> #include <complex> #include <functional> #include <iostream> #include <ranges> #include <string> #include <utility> #include <vector> int main() { namespace ranges = std::ranges; std::vector v{1, 2, 3, 4, 5, 6, 7, 8}; int sum = ranges::fold_left(v.begin(), v.end(), 0, std::plus<int>()); // (1) std::cout << "sum: " << sum << '\n'; int mul = ranges::fold_left(v, 1, std::multiplies<int>()); // (2) std::cout << "mul: " << mul << '\n'; // get the product of the std::pair::second of all pairs in the vector: std::vector<std::pair<char, float>> data {{'A', 2.f}, {'B', 3.f}, {'C', 3.5f}}; float sec = ranges::fold_left ( data | ranges::views::values, 2.0f, std::multiplies<>() ); std::cout << "sec: " << sec << '\n'; // use a program defined function object (lambda-expression): std::string str = ranges::fold_left ( v, "A", [](std::string s, int x) { return s + ':' + std::to_string(x); } ); std::cout << "str: " << str << '\n'; using CD = std::complex<double>; std::vector<CD> nums{{1, 1}, {2, 0}, {3, 0}}; #ifdef __cpp_lib_algorithm_default_value_type auto res = ranges::fold_left(nums, {7, 0}, std::multiplies{}); // (2) #else auto res = ranges::fold_left(nums, CD{7, 0}, std::multiplies{}); // (2) #endif std::cout << "res: " << res << '\n'; }
Ausgabe
sum: 36 mul: 40320 sec: 42 str: A:1:2:3:4:5:6:7:8 res: (42,42)
[edit] Referenzen
- C++23 Standard (ISO/IEC 14882:2024)
- 27.6.18 Fold [alg.fold]
[edit] Siehe auch
| (C++23) |
Faltet einen Elementbereich von links unter Verwendung des ersten Elements als Anfangswert (Algorithmus-Funktionsobjekt) |
| (C++23) |
Faltet einen Elementbereich von rechts (Algorithmus-Funktionsobjekt) |
| (C++23) |
Faltet einen Elementbereich von rechts unter Verwendung des letzten Elements als Anfangswert (Algorithmus-Funktionsobjekt) |
| (C++23) |
Faltet einen Elementbereich von links und gibt ein Paar (Iterator, Wert) zurück (Algorithmus-Funktionsobjekt) |
| Faltet einen Elementbereich von links unter Verwendung des ersten Elements als Anfangswert und gibt ein Paar (Iterator, optional) zurück (Algorithmus-Funktionsobjekt) | |
| summiert oder faltet eine Reihe von Elementen (Funktionstemplate) | |
| (C++17) |
ähnlich wie std::accumulate, aber nicht-sequenziell (Funktionstemplate) |