Namespaces
Variants

std::ranges::fold_left_first_with_iter, std::ranges::fold_left_first_with_iter_result

De fr.cppreference.net
 
 
Bibliothèque d'algorithmes
Algorithmes contraints et algorithmes sur plages (C++20)
Algorithmes contraints, par ex. ranges::copy, ranges::sort, ...
Opérations de séquence non modifiantes    
Opérations par lots
(C++17)
Opérations de recherche
Opérations de séquence modifiantes
Opérations de copie
(C++11)
(C++11)
Opérations d'échange
Opérations de transformation
Opérations de génération
Opérations de suppression
Opérations de changement d'ordre
(jusqu'à C++17)(C++11)
(C++20)(C++20)
Opérations d'échantillonnage
(C++17)

Tri et opérations associées
Opérations de partitionnement
(C++11)    

Opérations de tri
Opérations de recherche binaire
(sur plages partitionnées)
Opérations d'ensemble (sur plages triées)
Opérations de fusion (sur plages triées)
Opérations de tas
Opérations minimum/maximum
(C++11)
(C++17)
Opérations de comparaison lexicographique
Opérations de permutation


 
Algorithmes contraints
Tous les noms de ce menu appartiennent à l'espace de noms std::ranges
Opérations de séquence non modifiantes
Opérations de séquence modifiantes
Opérations de partitionnement
Opérations de tri
Opérations de recherche binaire (sur plages triées)
       
       
Opérations d'ensemble (sur plages triées)
Opérations de tas
Opérations minimum/maximum
       
       
Opérations de permutation
Opérations de pliage (fold)
Opérations sur le stockage non initialisé
Types de retour
 
Défini dans l'en-tête <algorithm>
Signature d'appel
template< std::input_iterator I, std::sentinel_for<I> S,
          /*indirectly-binary-left-foldable*/<std::iter_value_t<I>, I> F >
requires std::constructible_from<
             std::iter_value_t<I>, std::iter_reference_t<I>>
constexpr /* see description */
    fold_left_first_with_iter( I first, S last, F f );
(1) (depuis C++23)
template< ranges::input_range R,
          /*indirectly-binary-left-foldable*/<
              ranges::range_value_t<R>, ranges::iterator_t<R>> F >
requires std::constructible_from<
             ranges::range_value_t<R>, ranges::range_reference_t<R>>
constexpr /* see description */
    fold_left_first_with_iter( R&& r, F f );
(2) (depuis C++23)
Concepts auxiliaires
template< class F, class T, class I >
concept /*indirectly-binary-left-foldable*/ = /* see description */;
(3) (exposition uniquement*)
Gabarit de classe auxiliaire
template< class I, class T >
using fold_left_first_with_iter_result = ranges::in_value_result<I, T>;
(4) (depuis C++23)

Plie à gauche (left-fold) les éléments d'une plage donnée, c'est-à-dire retourne le résultat de l'évaluation de l'expression en chaîne :
f(f(f(f(x1, x2), x3), ...), xn), où x1, x2, ..., xn sont les éléments de la plage.

De manière informelle, ranges::fold_left_first_with_iter se comporte comme la surcharge de std::accumulate qui accepte un prédicat binaire, sauf que le *first est utilisé en interne comme élément initial.

Le comportement est indéfini si [firstlast) n'est pas une plage valide.

1) La plage est [firstlast).
2) Identique à (1), sauf qu'il utilise r comme plage, comme si en utilisant ranges::begin(r) comme first et ranges::end(r) comme last.
3) Équivalent à :
Concepts auxiliaires
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) (exposition uniquement*)
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) (exposition uniquement*)
4) L'alias de type de retour. Voir la section "Valeur de retour" pour les détails.

Les entités de type fonction décrites sur cette page sont des objets fonction d'algorithme (informellement connus sous le nom de niebloids), c'est-à-dire :

Paramètres

first, last - la paire itérateur-sentinelle définissant la plage d'éléments à plier
r - la plage d'éléments à plier
f - l'objet fonction binaire

Valeur de retour

Soit U égal à decltype(ranges::fold_left(std::move(first), last, std::iter_value_t<I>(*first), f)).

1) Un objet de type ranges::fold_left_first_with_iter_result<I, std::optional<U>>.
  • Le membre ranges::in_value_result::in contient un itérateur vers la fin de la plage.
  • Le membre ranges::in_value_result::value contient le résultat du pliage à gauche (left-fold) de la plage donnée avec f.
Si la plage est vide, la valeur de retour est {std::move(first), std::optional<U>()}.
2) Identique à (1) sauf que le type de retour est ranges::fold_left_first_with_iter_result<ranges::borrowed_iterator_t<R>, std::optional<U>>.

Implémentations possibles

class fold_left_first_with_iter_fn
{
    template<class O, class I, class S, class F>
    constexpr auto impl(I&& first, S&& last, F f) const
    {
        using U = decltype(
            ranges::fold_left(std::move(first), last, std::iter_value_t<I>(*first), f)
        );
        using Ret = ranges::fold_left_first_with_iter_result<O, std::optional<U>>;
        if (first == last)
            return Ret{std::move(first), std::optional<U>()};
        std::optional<U> init(std::in_place, *first);
        for (++first; first != last; ++first)
            *init = std::invoke(f, std::move(*init), *first);
        return Ret{std::move(first), std::move(init)};
    }

public:
    template<std::input_iterator I, std::sentinel_for<I> S,
             /*indirectly-binary-left-foldable*/<std::iter_value_t<I>, I> F>
    requires std::constructible_from<std::iter_value_t<I>, std::iter_reference_t<I>>
    constexpr auto operator()(I first, S last, F f) const
    {
        return impl<I>(std::move(first), std::move(last), std::ref(f));
    }

    template<ranges::input_range R, /*indirectly-binary-left-foldable*/<
        ranges::range_value_t<R>, ranges::iterator_t<R>> F>
    requires
        std::constructible_from<ranges::range_value_t<R>, ranges::range_reference_t<R>>
    constexpr auto operator()(R&& r, F f) const
    {
        return impl<ranges::borrowed_iterator_t<R>>(
            ranges::begin(r), ranges::end(r), std::ref(f)
        );
    }
};

inline constexpr fold_left_first_with_iter_fn fold_left_first_with_iter;

Complexité

Exactement ranges::distance(first, last) - 1 (en supposant que la plage n'est pas vide) applications de l'objet fonction f.

Notes

Le tableau suivant compare tous les algorithmes de pliage contraints :

Gabarit de fonction de pliage Commence à partir de Valeur initiale Type de retour
ranges::fold_left gauche init U
ranges::fold_left_first gauche premier élément std::optional<U>
ranges::fold_right droite init U
ranges::fold_right_last droite dernier élément std::optional<U>
ranges::fold_left_with_iter gauche init

(1) ranges::in_value_result<I, U>

(2) ranges::in_value_result<BR, U>,

BR est ranges::borrowed_iterator_t<R>

ranges::fold_left_first_with_iter gauche premier élément

(1) ranges::in_value_result<I, std::optional<U>>

(2) ranges::in_value_result<BR, std::optional<U>>

BR est ranges::borrowed_iterator_t<R>

Macro de test de fonctionnalité Valeur Norme Fonctionnalité
__cpp_lib_ranges_fold 202207L (C++23) std::ranges algorithmes de pliage

Exemple

#include <algorithm>
#include <cassert>
#include <functional>
#include <iostream>
#include <ranges>
#include <utility>
#include <vector>

int main()
{
    std::vector v{1, 2, 3, 4, 5, 6, 7, 8};

    auto sum = std::ranges::fold_left_first_with_iter
    (
        v.begin(), v.end(), std::plus<int>()
    );
    std::cout << "sum: " << sum.value.value() << '\n';
    assert(sum.in == v.end());

    auto mul = std::ranges::fold_left_first_with_iter(v, std::multiplies<int>());
    std::cout << "mul: " << mul.value.value() << '\n';
    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', 7.f}};
    auto sec = std::ranges::fold_left_first_with_iter
    (
        data | std::ranges::views::values, std::multiplies<>()
    );
    std::cout << "sec: " << sec.value.value() << '\n';

    // use a program defined function object (lambda-expression):
    auto lambda = [](int x, int y) { return x + y + 2; };
    auto val = std::ranges::fold_left_first_with_iter(v, lambda);
    std::cout << "val: " << val.value.value() << '\n';
    assert(val.in == v.end());
}

Sortie :

sum: 36
mul: 40320
sec: 42
val: 50

Références

  • Norme C++23 (ISO/IEC 14882:2024) :
  • 27.6.18 Pliage [alg.fold]

Voir aussi

plie à gauche une plage d'éléments
(objet fonction d'algorithme)
plie à gauche une plage d'éléments en utilisant le premier élément comme valeur initiale
(objet fonction d'algorithme)
plie à droite une plage d'éléments
(objet fonction d'algorithme)
plie à droite une plage d'éléments en utilisant le dernier élément comme valeur initiale
(objet fonction d'algorithme)
plie à gauche une plage d'éléments et retourne une paire (itérateur, valeur)
(objet fonction d'algorithme)
additionne ou plie une plage d'éléments
(gabarit de fonction)
(C++17)
similaire à std::accumulate, sauf hors ordre
(gabarit de fonction)