std::ranges::fold_left_with_iter, std::ranges::fold_left_with_iter_result
| 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*) |
| Hilfsklassentemplateat |
||
| template< class I, class T > using fold_left_with_iter_result = ranges::in_value_result<I, T>; |
(4) | (seit C++23) |
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_with_iter 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).| 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 |
[bearbeiten] 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 |
[bearbeiten] Rückgabewert
Sei U std::decay_t<std::invoke_result_t<F&, T, std::iter_reference_t<I>>>.
- Das Mitglied ranges::in_value_result::in enthält einen Iterator zum Ende des Bereichs.
- Das Mitglied ranges::in_value_result::value enthält das Ergebnis der Links-Faltung (Fold) des gegebenen Bereichs über f.
[bearbeiten] Mögliche Implementierungen
class fold_left_with_iter_fn { template<class O, class I, class S, class T, class F> constexpr auto impl(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>>>; using Ret = ranges::fold_left_with_iter_result<O, U>; if (first == last) return Ret{std::move(first), 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 Ret{std::move(first), std::move(accum)}; } public: 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 { return impl<I>(std::move(first), std::move(last), std::move(init), std::ref(f)); } 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 impl<ranges::borrowed_iterator_t<R>> ( ranges::begin(r), ranges::end(r), std::move(init), std::ref(f) ); } }; inline constexpr fold_left_with_iter_fn fold_left_with_iter; |
[bearbeiten] Komplexität
Genau ranges::distance(first, last) Anwendungen des Funktions-Objekts f.
[bearbeiten] Hinweise
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) |
[bearbeiten] Beispiel
#include <algorithm> #include <cassert> #include <complex> #include <functional> #include <ranges> #include <utility> #include <vector> int main() { namespace ranges = std::ranges; std::vector v{1, 2, 3, 4, 5, 6, 7, 8}; auto sum = ranges::fold_left_with_iter(v.begin(), v.end(), 6, std::plus<int>()); assert(sum.value == 42); assert(sum.in == v.end()); auto mul = ranges::fold_left_with_iter(v, 0X69, std::multiplies<int>()); assert(mul.value == 4233600); assert(mul.in == v.end()); // 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}}; auto sec = ranges::fold_left_with_iter ( data | ranges::views::values, 2.0f, std::multiplies<>() ); assert(sec.value == 42); // Use a program defined function object (lambda-expression): auto lambda = [](int x, int y){ return x + 0B110 + y; }; auto val = ranges::fold_left_with_iter(v, -42, lambda); assert(val.value == 42); assert(val.in == v.end()); 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_with_iter(nums, {7, 0}, std::multiplies{}); #else auto res = ranges::fold_left_with_iter(nums, CD{7, 0}, std::multiplies{}); #endif assert((res.value == CD{42, 42})); }
[bearbeiten] Referenzen
- C++23 Standard (ISO/IEC 14882:2024)
- 27.6.18 Fold [alg.fold]
[bearbeiten] Siehe auch
| (C++23) |
Faltet einen Elementbereich von links (Algorithmus-Funktionsobjekt) |
| (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) |
| 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) |