std::ranges::fold_right
| Definiert in Header <algorithm> |
||
| Aufruf-Signatur |
||
| (1) | ||
template< std::bidirectional_iterator I, std::sentinel_for<I> S, class T, /* indirectly-binary-right-foldable */<T, I> F > |
(seit C++23) (bis C++26) |
|
| template< std::bidirectional_iterator I, std::sentinel_for<I> S, class T = std::iter_value_t<I>, |
(seit C++26) | |
| (2) | ||
| template< ranges::bidirectional_range R, class T, /* indirectly-binary-right-foldable */ |
(seit C++23) (bis C++26) |
|
| template< ranges::bidirectional_range R, class T = ranges::range_value_t<R>, /* indirectly-binary-right-foldable */ |
(seit C++26) | |
| Hilfskonzepte |
||
| template< class F, class T, class I > concept /* indirectly-binary-left-foldable */ = /* see description */; |
(3) | (nur Exposition*) |
| template< class F, class T, class I > concept /* indirectly-binary-right-foldable */ = /* see description */; |
(4) | (nur Exposition*) |
Rechts-faltet die Elemente des gegebenen Bereichs, d.h. gibt das Ergebnis der Auswertung des Kettenausdrucks zurückf(x1, f(x2, ...f(xn, init))), wobei x1, x2, ..., xn Elemente des Bereichs sind.
Informell verhält sich ranges::fold_right wie ranges::fold_left(views::reverse(r), init, /*flipped*/(f)).
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*) |
| Hilfskonzepte |
||
| template< class F, class T, class I > concept /*indirectly-binary-right-foldable*/ = |
(4A) | (nur Exposition*) |
| Hilfsklassen-Templates |
||
| template< class F > class /*flipped*/ |
(4B) | (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 des Rechts-Faltens des gegebenen Bereichs über f enthält, wobei U äquivalent zu std::decay_t<std::invoke_result_t<F&, std::iter_reference_t<I>, T>>; ist.
Wenn der Bereich leer ist, wird U(std::move(init)) zurückgegeben.
[edit] Mögliche Implementierungen
struct fold_right_fn { template<std::bidirectional_iterator I, std::sentinel_for<I> S, class T = std::iter_value_t<I>, /* indirectly-binary-right-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&, std::iter_reference_t<I>, T>>; if (first == last) return U(std::move(init)); I tail = ranges::next(first, last); U accum = std::invoke(f, *--tail, std::move(init)); while (first != tail) accum = std::invoke(f, *--tail, std::move(accum)); return accum; } template<ranges::bidirectional_range R, class T = ranges::range_value_t<R>, /* indirectly-binary-right-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_right_fn fold_right; |
[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> using namespace std::literals; namespace ranges = std::ranges; int main() { auto v = {1, 2, 3, 4, 5, 6, 7, 8}; std::vector<std::string> vs{"A", "B", "C", "D"}; auto r1 = ranges::fold_right(v.begin(), v.end(), 6, std::plus<>()); // (1) std::cout << "r1: " << r1 << '\n'; auto r2 = ranges::fold_right(vs, "!"s, std::plus<>()); // (2) std::cout << "r2: " << r2 << '\n'; // Use a program defined function object (lambda-expression): std::string r3 = ranges::fold_right ( v, "A", [](int x, std::string s) { return s + ':' + std::to_string(x); } ); std::cout << "r3: " << r3 << '\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 r4 = ranges::fold_right ( data | ranges::views::values, 2.0f, std::multiplies<>() ); std::cout << "r4: " << r4 << '\n'; using CD = std::complex<double>; std::vector<CD> nums{{1, 1}, {2, 0}, {3, 0}}; #ifdef __cpp_lib_algorithm_default_value_type auto r5 = ranges::fold_right(nums, {7, 0}, std::multiplies{}); #else auto r5 = ranges::fold_right(nums, CD{7, 0}, std::multiplies{}); #endif std::cout << "r5: " << r5 << '\n'; }
Ausgabe
r1: 42 r2: ABCD! r3: A:8:7:6:5:4:3:2:1 r4: 42 r5: (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 rechts unter Verwendung des letzten Elements als Anfangswert (Algorithmus-Funktionsobjekt) |
| (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 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) |