Namespaces
Variants

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

From cppreference.net
Algorithm library
Constrained algorithms and algorithms on ranges (C++20)
Constrained algorithms, e.g. ranges::copy , ranges::sort , ...
Execution policies (C++17)
Non-modifying sequence operations
Batch operations
(C++17)
Search operations
Modifying sequence operations
Copy operations
(C++11)
(C++11)
Swap operations
Transformation operations
Generation operations
Removing operations
Order-changing operations
(until C++17) (C++11)
(C++20) (C++20)
Sampling operations
(C++17)

Sorting and related operations
Partitioning operations
Sorting operations
Binary search operations
(on partitioned ranges)
Set operations (on sorted ranges)
Merge operations (on sorted ranges)
Heap operations
Minimum/maximum operations
Lexicographical comparison operations
Permutation operations
C library
Numeric operations
Operations on uninitialized memory
Constrained algorithms
All names in this menu belong to namespace std::ranges
Non-modifying sequence operations
Modifying sequence operations
Partitioning operations
Sorting operations
Binary search operations (on sorted ranges)
Set operations (on sorted ranges)
Heap operations
Minimum/maximum operations
Permutation operations
Fold operations
fold_left_with_iter
(C++23)
Operations on uninitialized storage
Return types
Definido en el encabezado <algorithm>
Firma de llamada
(1)
template < std:: input_iterator I, std:: sentinel_for < I > S, class T,

/* indirectamente-plegable-binario-por-la-izquierda */ < T, I > F >
constexpr /* ver descripción */

fold_left_with_iter ( I first, S last, T init, F f ) ;
(desde C++23)
(hasta C++26)
template < std:: input_iterator I, std:: sentinel_for < I > S,

class T = std:: iter_value_t < I > ,
/* indirectamente-plegable-binario-por-la-izquierda */ < T, I > F >
constexpr /* ver descripción */

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

/* indirectamente-binario-plegable-por-la-izquierda */
< T, ranges:: iterator_t < R >> F >
constexpr /* ver descripción */

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

/* indirectamente-binario-plegable-por-la-izquierda */
< T, ranges:: iterator_t < R >> F >
constexpr /* ver descripción */

fold_left_with_iter ( R && r, T init, F f ) ;
(desde C++26)
Conceptos auxiliares
template < class F, class T, class I >
concept /* indirectly-binary-left-foldable */ = /* see description */ ;
(3) ( solo para exposición* )
Plantilla de clase auxiliar
template < class I, class T >
using fold_left_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(init, x 1 ), x 2 ), ...), x n ) , donde x 1 , x 2 , ..., x n son elementos del rango.

Informalmente, ranges::fold_left_with_iter se comporta como la sobrecarga de std::accumulate que acepta un predicado binario.

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

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

Las entidades similares a funciones descritas en esta página son algorithm function objects (conocidas informalmente como niebloids ), es decir:

Contenidos

Parámetros

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

Valor de retorno

Sea U el tipo std:: decay_t < std:: invoke_result_t < F & , T, std:: iter_reference_t < I >>> .

1) Un objeto de tipo ranges :: fold_left_with_iter_result < I, 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 se obtiene mediante una expresión equivalente a return { std :: move ( first ) , U ( std :: move ( init ) ) } ; .
2) Igual que (1) excepto que el tipo de retorno es ranges :: fold_left_with_iter_result < ranges:: borrowed_iterator_t < R > , U > .

Posibles implementaciones

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>,
             /* indirectamente-plegable-binario-por-la-izquierda */<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>,
             /* indirectamente-plegable-binario-por-la-izquierda */<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;

Complejidad

Exactamente ranges:: distance ( first, last ) aplicaciones del objeto función f .

Notas

La siguiente tabla compara todos los algoritmos de plegado restringido:

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
__cpp_lib_algorithm_default_value_type 202403L (C++26) Inicialización de lista para algoritmos ( 1,2 )

Ejemplo

#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());
    // 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', 3.5f}};
    auto sec = ranges::fold_left_with_iter
    (
        data | ranges::views::values, 2.0f, std::multiplies<>()
    );
    assert(sec.value == 42);
    // Usar un objeto función definido por el programa (expresión lambda):
    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}));
}

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 usando el primer elemento como valor inicial, y retorna un pair (iterador, optional )
(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)