Espacios de nombres
Variantes
Acciones

std::accumulate

De cppreference.com
< cpp‎ | algorithm
 
 
Biblioteca de algoritmos
Políticas de ejecución (C++17)
Operaciones de secuencia no modificantes
(C++11)(C++11)(C++11)
(C++17)
Operaciones de secuencia modificantes
Operaciones en almacenamiento no inicializado
Operaciones de partición
Operaciones de ordenación
(C++11)
Operaciones de búsqueda binaria
Operaciones de conjuntos (en rangos ordenados)
Operaciones de pila
(C++11)
Operaciones mínimo/máximo
(C++11)
(C++17)
Permutaciones
Operaciones numéricas
accumulate
(C++17)
Bibliotecas C
 
Definido en el archivo de encabezado <numeric>
(1)
template< class InputIt, class T >
T accumulate( InputIt first, InputIt last, T init );
(hasta C++20)
template< class InputIt, class T >
constexpr T accumulate( InputIt first, InputIt last, T init );
(desde C++20)
(2)
template< class InputIt, class T, class BinaryOperation >

T accumulate( InputIt first, InputIt last, T init,

              BinaryOperation op );
(hasta C++20)
template< class InputIt, class T, class BinaryOperation >

constexpr T accumulate( InputIt first, InputIt last, T init,

                        BinaryOperation op );
(desde C++20)

Calcula la suma del valor init dado y los elementos en el rango [first, last). La primera versión utiliza el operador operator+ para sumar los elementos; la segunda versión utiliza la función binaria dada op; ambas versiones aplican std::move a sus operandos del lado izquierdo (desde C++20).

op no debe tener efectos secundarios.

(hasta C++11)

op no debe invalidar ningún iterador, incluso los iteradores al final, ni modificar ningún elemento en el rango involucrado, ni tampoco a *last.

(desde C++11)
.

Contenido

[editar] Parámetros

first, last - El rango de elementos a sumar.
init - Valor inicial de la suma.
op - Función objeto de operación binaria que se aplicará. El operador binario toma el valor actual de la acumulación a (inicializado a init) y el valor del elemento actual b.

La signatura de la función deberá ser equivalente a lo siguiente:

 Ret fun(const Type1 &a, const Type2 &b);

La signatura no necesita tener const &.
El tipo Type1 debe ser tal que un objeto de tipo T puede convertirse implícitamente a Type1. El tipo Type2 debe ser tal que un objeto de tipo InputIt puede ser desreferenciado y luego convertido implícitamente a Type2. El tipo Ret debe ser tal que un objeto de tipo T puede ser asignado un valor de tipo Ret. ​

Requisitos de tipo
-
InputIt debe satisfacer los requisitos de InputIterator.
-
T debe satisfacer los requisitos de CopyAssignable y CopyConstructible.

[editar] Valor de retorno

1) La suma del valor y los elementos dados en el rango dado.
2) El resultado del pliegue izquierdo en el rango dado sobre op.

[editar] Notas

std::accumulate lleva a cabo un pliegue izquierdo. Para poder llevar a cabo un pliegue derecho, uno debe invertir el orden de los argumentos pasados al operador binario y utilizar iteradores inversos.

[editar] Errores más comunes

La operación op se realiza en el tipo de init, que puede inducir una conversión no deseada de los elementos. Por ejemplo, std::accumulate(v.begin(), v.end(), 0) da el resultado equivocado cuando v es std::vector<double>.

[editar] Posible implementación

Primera versión
template<class InputIt, class T>
constexpr // desde C++20
T accumulate(InputIt first, InputIt last, T init)
{
    for (; first != last; ++first) {
        init = std::move(init) + *first; // std::move desde C++20
    }
    return init;
}
Segunda versión
template<class InputIt, class T, class BinaryOperation>
constexpr // desde C++20
T accumulate(InputIt first, InputIt last, T init, 
             BinaryOperation op)
{
    for (; first != last; ++first) {
        init = op(std::move(init), *first); // std::move desde C++20
    }
    return init;
}

[editar] Ejemplo

#include <iostream>
#include <vector>
#include <numeric>
#include <string>
#include <functional>
 
int main()
{
    std::vector<int> v{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
 
    int sum = std::accumulate(v.begin(), v.end(), 0);
 
    int product = std::accumulate(v.begin(), v.end(), 1, std::multiplies<int>());
 
    auto dash_fold = [](std::string a, int b) {
                         return std::move(a) + '-' + std::to_string(b);
                     };
 
    std::string s = std::accumulate(std::next(v.begin()), v.end(),
                                    std::to_string(v[0]), // iniciar con el
                                    dash_fold);           // primer elemento
 
    // Pliegue derecho usando iteradores inversos
    std::string rs = std::accumulate(std::next(v.rbegin()), v.rend(),
                                     std::to_string(v.back()), // iniciar con el
                                     dash_fold);               // último elemento
 
    std::cout << "suma: " << sum << '\n'
              << "producto: " << product << '\n'
              << "cadena separada por guiones: " << s << '\n'
              << "cadena separada por guiones (plegada a la derecha): " << rs << '\n';
}

Salida:

suma: 55
producto: 3628800
cadena separada por guiones: 1-2-3-4-5-6-7-8-9-10
cadena separada por guiones (plegada a la derecha): 10-9-8-7-6-5-4-3-2-1

[editar] Véase también

Calcula las diferencias entre elementos adyacentes en un rango
(plantilla de función) [editar]
Calcula el producto interno de dos rangos de elementos
(plantilla de función) [editar]
Calcula la suma parcial de un rango de elementos
(plantilla de función) [editar]
(C++17)
Similar a std::accumulate, excepto que fuera de orden
(plantilla de función) [editar]