std::transform_exclusive_scan
Definido en el archivo de encabezado <numeric> | ||
(1) | ||
template<class InputIt, class OutputIt, class T, class BinaryOperation, class UnaryOperation> | (desde C++17) (hasta C++20) | |
template<class InputIt, class OutputIt, class T, class BinaryOperation, class UnaryOperation> | (desde C++20) | |
template<class ExecutionPolicy, class ForwardIt1, class ForwardIt2, | (2) | (desde C++17) |
Transforma cada elemento en el rango [first, last)
con unary_op
, luego calcula una suma de prefijo exclusiva utilizando binary_op
sobre el rango resultante, con init
as the initial value, como el valor inicial, y escribe los resultados en el rango que comienza en d_first
. "Exclusiva" significa que el i-ésimo elemento de entrada no se incluye en la i-ésima suma.
Formalmente, asigna a través de cada iterador i
en [d_first, d_first + (last - first)) el valor de la suma generalizada no conmutativa de init, unary_op(*j)...
para toda j
en [first, first + (i - d_first)) sobre binary_op
,
donde la suma generalizada no conmutativa de GNSUM(op, a
1, ..., a
N) se define de la manera siguiente:
- si N=1, a
1 - si N > 1, op(GNSUM(op, a
1, ..., a
K), GNSUM(op, a
M, ..., a
N)) para cualquier K donde 1 < K+1 = M ≤ N
En otras palabras, las operaciones de suma pueden realizarse en orden arbitrario, y el comportamiento no es determinista si binary_op
no es asociativa.
La sobrecarga (2) se ejecuta de acuerdo a la política de ejecución policy
. Esta sobrecarga no participa 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.
unary_op
y binary_op
no deberán invalidar interadores (incluyendo los iteradores al final) o subrangos, ni modificar elementos en los rangos [first, last) o [d_first, d_first + (last - first)). De lo contrario, el comportamiento está indefinido.
Contenido |
[editar]Parámetros
first, last | - | El rango de elementos a sumar. |
d_first | - | El inicio del rango destino; puede ser igual a first |
policy | - | La política de ejecución a usar. Véase política de ejecución para más detalles. |
init | - | El valor inicial. |
unary_op | - | Objeto función (FunctionObject) unario que se aplicará a cada elemento del rango de entrada. El valor de retorno deberá ser aceptable como entrada para binary_op . |
binary_op | - | Objeto función (FunctionObject) binario que se aplicará al resultado de unary_op , los resultados de otras binary_op , e init . |
Requisitos de tipo | ||
-InputIt debe satisfacer los requisitos de InputIterator. | ||
-OutputIt debe satisfacer los requisitos de OutputIterator. | ||
-ForwardIt1, ForwardIt2 debe satisfacer los requisitos de ForwardIterator. | ||
-T debe satisfacer los requisitos de MoveConstructible. Todos los siguientes, binary_op(init, unary_op(*first)) , binary_op(init, init) , y binary_op(unary_op(*first), unary_op(*first)) deben ser convertibles a T . |
[editar]Valor de retorno
Iterador al elemento después del último elemento escrito.
[editar]Complejidad
O(last - first) aplicaciones de binary_op
y unary_op
.
[editar]Excepciones
La sobrecarga con un parámetro de plantilla llamado ExecutionPolicy
(política de ejecución) reporta 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
unary_op
no se aplica a init
.
[editar]Ejemplo
#include <functional>#include <iostream>#include <iterator>#include <numeric>#include <vector> int times_10(int x){return x *10;} int main(){std::vector data {3, 1, 4, 1, 5, 9, 2, 6}; std::cout<<"10 veces suma exclusiva: "; std::transform_exclusive_scan(data.begin(), data.end(), std::ostream_iterator<int>(std::cout, " "), 0, std::plus<int>{}, times_10);std::cout<<"\n10 veces suma inclusiva: ";std::transform_inclusive_scan(data.begin(), data.end(), std::ostream_iterator<int>(std::cout, " "), std::plus<int>{}, times_10);}
Salida:
10 veces suma exclusiva: 0 30 40 80 90 140 230 250 10 veces suma inclusiva: 30 40 80 90 140 230 250 310
[editar]Véase también
Calcula la suma parcial de un rango de elementos (plantilla de función) | |
(C++17) | Similar a std::partial_sum, excluye el i-ésimo elemento de entrada de la i-ésima suma (plantilla de función) |
(C++17) | Aplica un invocable, luego calcula la suma de prefijo (o suma acumulativa) inclusiva (plantilla de función) |