std:: accumulate
|
Definido en el encabezado
<numeric>
|
||
|
template
<
class
InputIt,
class
T
>
T accumulate ( InputIt first, InputIt last, T init ) ; |
(1) | (constexpr desde C++20) |
|
template
<
class
InputIt,
class
T,
class
BinaryOp
>
T accumulate ( InputIt first, InputIt last, T init, BinaryOp op ) ; |
(2) | (constexpr desde C++20) |
Calcula la suma del valor dado
init
y los elementos en el rango
[
first
,
last
)
.
T
) con el valor inicial
init
y luego lo modifica con
acc
=
acc
+
*
i
(hasta C++20)
acc
=
std
::
move
(
acc
)
+
*
i
(desde C++20)
para cada iterador
i
en el rango
[
first
,
last
)
en orden.
T
) con el valor inicial
init
y luego lo modifica con
acc
=
op
(
acc,
*
i
)
(hasta C++20)
acc
=
op
(
std
::
move
(
acc
)
,
*
i
)
(desde C++20)
para cada iterador
i
en el rango
[
first
,
last
)
en orden.
Si se satisface cualquiera de las siguientes condiciones, el comportamiento es indefinido:
-
Tno es CopyConstructible . -
Tno es CopyAssignable . -
op
modifica cualquier elemento de
[first,last). -
op
invalida cualquier iterador o subrango en
[first,last].
Contenidos |
Parámetros
| first, last | - | el par de iteradores que define el rango de elementos a acumular |
| init | - | valor inicial de la acumulación |
| op | - |
objeto función de operación binaria que será aplicado.
La firma de la función debe ser equivalente a la siguiente: Ret fun ( const Type1 & a, const Type2 & b ) ;
La firma no necesita tener
const
&
.
|
| Requisitos de tipo | ||
-
InputIt
debe cumplir con los requisitos de
LegacyInputIterator
.
|
||
Valor de retorno
acc después de todas las modificaciones.
Implementación posible
| accumulate (1) |
|---|
template<class InputIt, class T> constexpr // since C++20 T accumulate(InputIt first, InputIt last, T init) { for (; first != last; ++first) init = std::move(init) + *first; // std::move since C++20 return init; } |
| accumulate (2) |
template<class InputIt, class T, class BinaryOperation> constexpr // since C++20 T accumulate(InputIt first, InputIt last, T init, BinaryOperation op) { for (; first != last; ++first) init = op(std::move(init), *first); // std::move since C++20 return init; } |
Notas
std::accumulate
realiza un
plegado
hacia la izquierda. Para realizar un plegado hacia la derecha, se debe invertir el orden de los argumentos al operador binario y utilizar iteradores inversos.
Si se deja a la inferencia de tipos, op opera sobre valores del mismo tipo que init lo cual puede resultar en conversiones no deseadas de los elementos del iterador. Por ejemplo, std :: accumulate ( v. begin ( ) , v. end ( ) , 0 ) probablemente no da el resultado que se desea cuando v es de tipo std:: vector < double > .
Ejemplo
#include <functional> #include <iostream> #include <numeric> #include <string> #include <vector> 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]), // comenzar con el primer elemento dash_fold); // Plegado hacia la derecha usando iteradores inversos std::string rs = std::accumulate(std::next(v.rbegin()), v.rend(), std::to_string(v.back()), // comenzar con el último elemento dash_fold); std::cout << "suma: " << sum << '\n' << "producto: " << product << '\n' << "cadena separada por guiones: " << s << '\n' << "cadena separada por guiones (plegado derecho): " << 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 (plegado derecho): 10-9-8-7-6-5-4-3-2-1
Informes de defectos
Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares de C++ publicados anteriormente.
| DR | Aplicado a | Comportamiento publicado | Comportamiento correcto |
|---|---|---|---|
| LWG 242 | C++98 | op no podía tener efectos secundarios | no puede modificar los rangos involucrados |
Véase también
|
calcula las diferencias entre elementos adyacentes en un rango
(plantilla de función) |
|
|
calcula el producto interno de dos rangos de elementos
(plantilla de función) |
|
|
calcula la suma parcial de un rango de elementos
(plantilla de función) |
|
|
(C++17)
|
similar a
std::accumulate
, excepto fuera de orden
(plantilla de función) |
|
(C++23)
|
pliega hacia la izquierda un rango de elementos
(objeto función de algoritmo) |