Namespaces
Variants

std::ranges::fold_left_first

De es.cppreference.net
 
 
Biblioteca de algoritmos
Algoritmos restringidos y algoritmos sobre rangos (C++20)
Algoritmos restringidos, por ejemplo ranges::copy, ranges::sort, ...
Operaciones de secuencia no modificadoras    
Operaciones por lotes
(C++17)
Operaciones de búsqueda
Operaciones de secuencia modificadoras
Operaciones de copia
(C++11)
(C++11)
Operaciones de intercambio
Operaciones de transformación
Operaciones de generación
Operaciones de eliminación
Operaciones de cambio de orden
(hasta C++17)(C++11)
(C++20)(C++20)
Operaciones de muestreo
(C++17)

Ordenación y operaciones relacionadas
Operaciones de particionado
(C++11)    

Operaciones de ordenación
Operaciones de búsqueda binaria
(en rangos particionados)
Operaciones de conjunto (en rangos ordenados)
Operaciones de mezcla (en rangos ordenados)
Operaciones de montículo
Operaciones de mínimo/máximo
(C++11)
(C++17)
Operaciones de comparación lexicográfica
Operaciones de permutación


 
Algoritmos restringidos
Todos los nombres en este menú pertenecen al espacio de nombres std::ranges
Operaciones de secuencia no modificadoras
Operaciones de secuencia modificadoras
Operaciones de particionado
Operaciones de ordenación
Operaciones de búsqueda binaria (en rangos ordenados)
       
       
Operaciones de conjunto (en rangos ordenados)
Operaciones de montículo
Operaciones de mínimo/máximo
       
       
Operaciones de permutación
Operaciones de plegado
Operaciones sobre almacenamiento no inicializado
Tipos de retorno
 
Definido en el encabezado <algorithm>
Firma de la llamada
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
    fold_left_first( I first, S last, F f );
(1) (desde 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 auto
    fold_left_first( R&& r, F f );
(2) (desde C++23)
Conceptos auxiliares
template< class F, class T, class I >
concept /*indirectly-binary-left-foldable*/ = /* see description */;
(3) (solo exposición*)

Plegado a la izquierda de los elementos de un rango dado, es decir, devuelve el resultado de evaluar la expresión en cadena:
f(f(f(f(x1, x2), x3), ...), xn), donde x1, x2, ..., xn son elementos del rango.

Informalmente, ranges::fold_left_first se comporta como la sobrecarga de std::accumulate que acepta un predicado binario, excepto que se usa *first internamente como elemento inicial.

El comportamiento no está definido si [first, last) no es un rango válido.

1) El rango es [first, last). Equivalente a return ranges::fold_left_first_with_iter(std::move(first), last, f).value.
2) Igual que (1), excepto que usa r como el rango, como si usara ranges::begin(r) como first y ranges::end(r) como last.
3) Equivalente a:
Conceptos auxiliares
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) (solo exposición*)
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) (solo exposición*)

Las entidades similares a funciones descritas en esta página son objetos de función de algoritmo (conocidos informalmente como niebloids), es decir:

Parámetros

first, last - el par iterador-centinela que define el rango de elementos a plegar
r - el rango de elementos a plegar
f - el objeto función binaria

Valor de retorno

Un objeto de tipo std::optional<U> que contiene el resultado del plegado a la izquierda del rango dado sobre f, donde U es equivalente a decltype(ranges::fold_left(std::move(first), last, std::iter_value_t<I>(*first), f)).

Si el rango está vacío, se devuelve std::optional<U>().

Posibles implementaciones

struct fold_left_first_fn
{
    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
    {
        using U = decltype(
            ranges::fold_left(std::move(first), last, std::iter_value_t<I>(*first), f)
        );
        if (first == last)
            return 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 std::move(init);
    }

    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 (*this)(ranges::begin(r), ranges::end(r), std::ref(f));
    }
};

inline constexpr fold_left_first_fn fold_left_first;

Complejidad

Exactamente ranges::distance(first, last) - 1 (suponiendo que el rango no está vacío) aplicaciones del objeto función f.

Notas

La siguiente tabla compara todos los algoritmos de plegado restringidos:

Plantilla de función de plegado Comienza desde Valor inicial Tipo de retorno
ranges::fold_left izquierda init U
ranges::fold_left_first izquierda primer elemento std::optional<U>
ranges::fold_right derecha init U
ranges::fold_right_last derecha último elemento std::optional<U>
ranges::fold_left_with_iter izquierda init

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

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

donde BR es ranges::borrowed_iterator_t<R>

ranges::fold_left_first_with_iter izquierda primer elemento

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

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

donde BR es ranges::borrowed_iterator_t<R>

Macro de prueba de características Valor Estándar Característica
__cpp_lib_ranges_fold 202207L (C++23) std::ranges algoritmos de plegado

Ejemplo

#include <algorithm>
#include <array>
#include <functional>
#include <ranges>
#include <utility>

int main()
{
    constexpr std::array v{1, 2, 3, 4, 5, 6, 7, 8};
    static_assert
    (
        *std::ranges::fold_left_first(v.begin(), v.end(), std::plus{}) == 36
        && *std::ranges::fold_left_first(v, std::multiplies{}) == 40320
    );

    constexpr std::array w
    {
        1, 2, 3, 4, 13,
        1, 2, 3, 4, 13,
        1, 2, 3, 4, 13,
        1, 2, 3, 4,
    };
    static_assert
    (
        "Find the only value that (by precondition) occurs odd number of times:"
        && *std::ranges::fold_left_first(w, [](int p, int q){ return p ^ q; }) == 13
    );

    constexpr auto pairs = std::to_array<std::pair<char, float>>
    ({
        {'A', 3.0f},
        {'B', 3.5f},
        {'C', 4.0f}
    });
    static_assert
    (
        "Get the product of all pair::second in pairs:"
        && *std::ranges::fold_left_first
        (
            pairs | std::ranges::views::values, std::multiplies{}
        ) == 42
    );
}

Referencias

  • Estándar C++23 (ISO/IEC 14882:2024):
  • 27.6.18 Plegado [alg.fold]

Véase también

pliega a la izquierda un rango de elementos
(objeto de función de algoritmo)
pliega a la derecha un rango de elementos
(objeto de función de algoritmo)
pliega a la derecha un rango de elementos usando el último elemento como valor inicial
(objeto de función de algoritmo)
pliega a la izquierda un rango de elementos, y devuelve un par (iterador, valor)
(objeto de función de algoritmo)
pliega a la izquierda un rango de elementos usando el primer elemento como valor inicial, y devuelve un par (iterador, opcional)
(objeto de función de algoritmo)
suma o pliega un rango de elementos
(plantilla de función)
(C++17)
similar a std::accumulate, excepto que no es en orden
(plantilla de función)