Namespaces
Variants

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

De es.cppreference.net
 
 
Biblioteca de algoritmos
Algoritmos restringidos y algoritmos sobre rangos (C++20)
Algoritmos restringidos, p. ej. 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)

Operaciones de ordenación y 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 fusión (en rangos ordenados)
Operaciones de heap
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 heap
Operaciones de mínimo/máximo
       
       
Operaciones de permutación
Operaciones de pliegue (fold)
Operaciones sobre almacenamiento no inicializado
Tipos de retorno
 
Definido en el encabezado <algorithm>
Firma de 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 /* see description */
    fold_left_first_with_iter( 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 /* see description */
    fold_left_first_with_iter( 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 de exposición*)
Plantilla de clase auxiliar
template< class I, class T >
using fold_left_first_with_iter_result = ranges::in_value_result<I, T>;
(4) (desde C++23)

Pliega por la izquierda los elementos del rango dado, es decir, devuelve el resultado de la evaluación de 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_with_iter se comporta como la sobrecarga de std::accumulate que acepta un predicado binario, excepto que *first se usa internamente como elemento inicial.

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

1) El rango es [first, last).
2) Igual que (1), excepto que usa r como rango, como si se 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 de 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 de exposición*)
4) El alias del tipo de retorno. Consulte la sección "Valor de retorno" para más detalles.

Las entidades similares a funciones descritas en esta página son objetos 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 de función binaria

Valor de retorno

Sea U el tipo decltype ( ranges:: fold_left ( std :: move ( first ) , last, std:: iter_value_t < I > ( * first ) , f ) ) .

1) Un objeto de tipo ranges :: fold_left_first_with_iter_result < I, std:: optional < U >> .
  • El miembro ranges :: in_value_result :: in contiene un iterador al final del rango.
  • El miembro ranges :: in_value_result :: value contiene el resultado del plegado izquierdo del rango dado sobre f .
Si el rango está vacío, el valor de retorno es { std :: move ( first ) , std:: optional < U > ( ) } .
2) Igual que (1) excepto que el tipo de retorno es ranges :: fold_left_first_with_iter_result < ranges:: borrowed_iterator_t < R > , std:: optional < U >> .

Posibles implementaciones

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;

Complejidad

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

Notas

La siguiente tabla compara todos los algoritmos de plegado restringido:

Plantilla de función fold 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 <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());
    // obtener el producto del std::pair::second de todos los pares en el 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';
    // usar un objeto función definido por el programa (expresión lambda):
    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());
}

Salida:

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

Referencias

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

Véase también

pliega hacia la izquierda un rango de elementos
(objeto función de algoritmo)
pliega hacia la izquierda un rango de elementos usando el primer elemento como valor inicial
(objeto función de algoritmo)
pliega hacia la derecha un rango de elementos
(objeto función de algoritmo)
pliega hacia la derecha un rango de elementos usando el último elemento como valor inicial
(objeto función de algoritmo)
pliega hacia la izquierda un rango de elementos, y retorna un pair (iterador, valor)
(objeto función de algoritmo)
suma o pliega un rango de elementos
(plantilla de función)
(C++17)
similar a std::accumulate , excepto fuera de orden
(plantilla de función)