Namensräume
Varianten
Aktionen

std::ranges::fold_right

Von cppreference.com
< cpp‎ | algorithm‎ | ranges
 
 
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
(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
 
Eingeschränkte Algorithmen
Alle Namen in diesem Menü gehören zum Namespace std::ranges
Nicht-modifizierende Sequenzoperationen
Modifizierende Sequenzoperationen
Partitionierungsoperationen
Sortieroperationen
Binäre Suchoperationen (auf sortierten Bereichen)
       
       
Mengenoperationen (auf sortierten Bereichen)
Heapoperationen
Minimum/Maximum-Operationen
       
       
Permutationsoperationen
Faltoperationen
(C++23)
(C++23)  
fold_right
(C++23)
(C++23)  
Operationen auf uninitialisiertem Speicher
Rückgabetypen
 
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 >

constexpr auto fold_right( I first, S last, T init, F f );
(seit C++23)
(bis C++26)
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 fold_right( I first, S last, T init, F f );
(seit C++26)
(2)
template< ranges::bidirectional_range R, class T,

          /* indirectly-binary-right-foldable */
              <T, ranges::iterator_t<R>> F >

constexpr auto fold_right( R&& r, T init, F f );
(seit C++23)
(bis C++26)
template< ranges::bidirectional_range R, class T = ranges::range_value_t<R>,

          /* indirectly-binary-right-foldable */
              <T, ranges::iterator_t<R>> F >

constexpr auto fold_right( R&& r, T init, F f );
(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ück
f(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 [firstlast) kein gültiger Bereich ist.

1) Der Bereich ist [firstlast).
2) Wie (1), mit der Ausnahme, dass r als Bereich verwendet wird, als ob mit ranges::begin(r) als first und ranges::end(r) als last.
3) Äquivalent zu
Hilfskonzepte
template< class F, class T, class I, class U >

concept /*indirectly-binary-left-foldable-impl*/ =
    std::movable<T> &&
    std::movable<U> &&
    std::convertible_to<T, U> &&
    std::invocable<F&, U, std::iter_reference_t<I>> &&
    std::assignable_from<U&,

        std::invoke_result_t<F&, U, std::iter_reference_t<I>>>;
(3A) (nur Exposition*)
template< class F, class T, class I >

concept /*indirectly-binary-left-foldable*/ =
    std::copy_constructible<F> &&
    std::indirectly_readable<I> &&
    std::invocable<F&, T, std::iter_reference_t<I>> &&
    std::convertible_to<std::invoke_result_t<F&, T, std::iter_reference_t<I>>,
        std::decay_t<std::invoke_result_t<F&, T, std::iter_reference_t<I>>>> &&
    /*indirectly-binary-left-foldable-impl*/<F, T, I,

        std::decay_t<std::invoke_result_t<F&, T, std::iter_reference_t<I>>>>;
(3B) (nur Exposition*)
4) Äquivalent zu
Hilfskonzepte
template< class F, class T, class I >

concept /*indirectly-binary-right-foldable*/ =

    /*indirectly-binary-left-foldable*/</*flipped*/<F>, T, I>;
(4A) (nur Exposition*)
Hilfsklassen-Templates
template< class F >

class /*flipped*/
{
    F f;    // exposition only
public:
    template< class T, class U >
        requires std::invocable<F&, U, T>
    std::invoke_result_t<F&, U, T> operator()(typename std::iter_reference_t<I> &&);

};
(4B) (nur Exposition*)

Die auf dieser Seite beschriebenen funktionsähnlichen Entitäten sind Algorithmus-Funktionsobjekte (informell als niebloids bekannt), d.h.

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

Faltet einen Elementbereich von rechts unter Verwendung des letzten Elements als Anfangswert
(Algorithmus-Funktionsobjekt)[edit]
Faltet einen Elementbereich von links
(Algorithmus-Funktionsobjekt)[edit]
Faltet einen Elementbereich von links unter Verwendung des ersten Elements als Anfangswert
(Algorithmus-Funktionsobjekt)[edit]
Faltet einen Elementbereich von links und gibt ein Paar (Iterator, Wert) zurück
(Algorithmus-Funktionsobjekt)[edit]
Faltet einen Elementbereich von links unter Verwendung des ersten Elements als Anfangswert und gibt ein Paar (Iterator, optional) zurück
(Algorithmus-Funktionsobjekt)[edit]
summiert oder faltet eine Reihe von Elementen
(Funktionstemplate) [bearbeiten]
(C++17)
ähnlich wie std::accumulate, aber nicht-sequenziell
(Funktionstemplate) [bearbeiten]