Namensräume
Varianten
Aktionen

std::ranges::fold_left_with_iter, std::ranges::fold_left_with_iter_result

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)  
(C++23)
(C++23)  
fold_left_with_iter
(C++23)
Operationen auf uninitialisiertem Speicher
Rückgabetypen
 
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 >
constexpr /* siehe Beschreibung */

    fold_left_with_iter( I first, S last, T init, F f );
(seit C++23)
(bis C++26)
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 /* siehe Beschreibung */

    fold_left_with_iter( I first, S last, T init, F f );
(seit C++26)
(2)
template< ranges::input_range R, class T,

          /* indirectly-binary-left-foldable */
              <T, ranges::iterator_t<R>> F >
constexpr /* siehe Beschreibung */

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

          /* indirectly-binary-left-foldable */
              <T, ranges::iterator_t<R>> F >
constexpr /* siehe Beschreibung */

    fold_left_with_iter( 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*)
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ück
f(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 [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) Der Rückgabetypalias. Siehe Abschnitt "Rückgabewert" für Details.

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

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>>>.

1) Ein Objekt vom Typ ranges::fold_left_with_iter_result<I, U>.
  • 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.
Wenn der Bereich leer ist, wird der Rückgabewert durch den Ausdruck erzielt, der äquivalent zu return {std::move(first), U(std::move(init))}; ist.
2) Dasselbe wie (1), mit der Ausnahme, dass der Rückgabetyp ranges::fold_left_with_iter_result<ranges::borrowed_iterator_t<R>, U> ist.

[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

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 rechts
(Algorithmus-Funktionsobjekt)[edit]
Faltet einen Elementbereich von rechts unter Verwendung des letzten Elements als Anfangswert
(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]