std::reduce
Definido en el archivo de encabezado <numeric>
|
||
(1) | ||
template<class InputIt> typename std::iterator_traits<InputIt>::value_type reduce( |
(desde C++17) (hasta C++20) |
|
template<class InputIt> constexpr typename std::iterator_traits<InputIt>::value_type reduce( |
(desde C++20) | |
template<class ExecutionPolicy, class ForwardIt> typename std::iterator_traits<ForwardIt>::value_type reduce( |
(2) | (desde C++17) |
(3) | ||
template<class InputIt, class T> T reduce(InputIt first, InputIt last, T init); |
(desde C++17) (hasta C++20) |
|
template<class InputIt, class T> constexpr T reduce(InputIt first, InputIt last, T init); |
(desde C++20) | |
template<class ExecutionPolicy, class ForwardIt, class T> T reduce(ExecutionPolicy&& policy, |
(4) | (desde C++17) |
(5) | ||
template<class InputIt, class T, class BinaryOp> T reduce(InputIt first, InputIt last, T init, BinaryOp binary_op); |
(desde C++17) (hasta C++17) |
|
template<class InputIt, class T, class BinaryOp> constexpr T reduce(InputIt first, InputIt last, T init, BinaryOp binary_op); |
(desde C++17) | |
template<class ExecutionPolicy, class ForwardIt, class T, class BinaryOp> T reduce(ExecutionPolicy&& policy, |
(6) | (desde C++17) |
init
sobre binary_op
. policy
. Estas sobrecargas no participan en la resolución de sobrecarga a menos que std::is_execution_policy_v<std::decay_t<ExecutionPolicy>> (hasta C++20) std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>> (desde C++20) sea verdadera.El comportamiento es no-determinístico si binary_op
es no-asociativa o no-conmutativa.
El comportamiento está indefinido si binary_op
modifica cualquier elemento o invalida cualquier iterador en [first; last], incluyendo el iterador al final.
Contenido |
[editar] Parámetros
first, last | - | El rango de elementos al cual aplicar el algoritmo. |
init | - | El valor inicial de la suma generalizada |
policy | - | La política de ejecución a usar. Véase política de ejecución para más detalles. |
binary_op | - | FunctionObject, un objeto función binario que se aplicará en un orden inespecífico al resultado de desreferenciar los iteradores de entrada, los resultados de otras operaciones binarias binary_op e init .
|
Requisitos de tipo | ||
-InputIt debe satisfacer los requisitos de InputIterator.
| ||
-ForwardIt debe satisfacer los requisitos de ForwardIterator.
| ||
-T debe satisfacer los requisitos de MoveConstructible. y binary_op(init, *first) , binary_op(*first, init) , binary_op(init, init) , y binary_op(*first, *first) deben ser convertibles a T .
|
[editar] Valor de retorno
La suma generalizada de init
y *first
, *(first+1)
, ... *(last-1)
sobre binary_op
,
donde la suma generalizada GSUM(op, a
1, ..., a
N) se define de la manera siguiente:
- si N=1, a
1 - si N > 1, op(GSUM(op, b
1, ..., b
K), GSUM(op, b
M, ..., b
N)) donde
- b
1, ..., b
N puede ser cualquier permutación de a1, ..., aN y - 1 < K+1 = M ≤ N
- b
en otras palabras, reduce
se comporta como std::accumulate, excepto que los elementos del rango pueden agruparse y reorganizarse en orden arbitrario.
[editar] Complejidad
O(last - first) aplicaciones de binary_op
.
[editar] Excepciones
Las sobrecargas con un parámetro de plantilla llamado ExecutionPolicy
(política de ejecución) reportan errores tales que:
- Si la ejecución de una función invocada como parte del algoritmo lanza una excepción y la política de ejecución es una de las tres políticas estándar, se llama a std::terminate. Para cualquier otra política de ejecución, el comportamiento está definido por la implementación.
- Si el algoritmo falla al asignar memoria, se lanza std::bad_alloc.
[editar] Notas
Si el rango está vacío, se devuelve init
sin modificar.
[editar] Ejemplo
Comparación lado a lado entre reduce y std::accumulate:
#include <iostream> #include <chrono> #include <vector> #include <numeric> #include <execution> int main() { const std::vector<double> v(10'000'007, 0.5); { const auto t1 = std::chrono::high_resolution_clock::now(); const double result = std::accumulate(v.cbegin(), v.cend(), 0.0); const auto t2 = std::chrono::high_resolution_clock::now(); const std::chrono::duration<double, std::milli> ms = t2 - t1; std::cout << std::fixed << "resultado de std::accumulate " << result << " toma " << ms.count() << " ms\n"; } { const auto t1 = std::chrono::high_resolution_clock::now(); const double result = std::reduce(std::execution::par, v.cbegin(), v.cend()); const auto t2 = std::chrono::high_resolution_clock::now(); const std::chrono::duration<double, std::milli> ms = t2 - t1; std::cout << "resultado de std::reduce " << result << " toma " << ms.count() << " ms\n"; } }
Posible salida:
resultado de std::accumulate 5000003.50000 toma 12.7365 ms resultado de std::reduce 5000003.50000 toma 5.06423 ms
[editar] Véase también
Suma un rango de elementos (plantilla de función) | |
Aplica una función a un rango de elementos (plantilla de función) | |
(C++17) |
Aplica un invocable, luego reduce fuera de orden (plantilla de función) |