std::transform_reduce
Defined in header <numeric>


template<class InputIt1, class InputIt2, class T> T transform_reduce(InputIt1 first1, InputIt1 last1, InputIt2 first2, T init); 
(1)  (since C++17) 
template <class InputIt1, class InputIt2, class T, class BinaryOp1, class BinaryOp2> T transform_reduce(InputIt1 first1, InputIt1 last1, InputIt2 first2, 
(2)  (since C++17) 
template<class InputIt, class T, class BinaryOp, class UnaryOp> T transform_reduce(InputIt first, InputIt last, 
(3)  (since C++17) 
template<class ExecutionPolicy, class ForwardIt1, class ForwardIt2, class T> 
(4)  (since C++17) 
template<class ExecutionPolicy, class ForwardIt1, class ForwardIt2, class T, class BinaryOp1, class BinaryOp2> 
(5)  (since C++17) 
template<class ExecutionPolicy, class ForwardIt, class T, class BinaryOp, class UnaryOp> 
(6)  (since C++17) 
transform_reduce(first1, last1, first2, init, std::plus<>(), std::multiplies<>());
, effectively parallelized version of the default std::inner_productbinary_op2
to each pair of elements from the ranges [first; last) and the range starting at first2 and reduces the results (possibly permuted and aggregated in unspecified manner) along with the initial value init
over binary_op1
unary_op
to each element in the range [first; last) and reduces the results (possibly permuted and aggregated in unspecified manner) along with the initial value init
over binary_op
.policy
. This overload only participates in overload resolution if std::is_execution_policy_v<std::decay_t<ExecutionPolicy>> is trueThe behavior is nondeterministic if binary_op
/binary_op2
is not associative or not commutative.
The behavior is undefined if unary_op
, binary_op
, binary_op1
, or binary_op2
modifies any element or invalidates any iterator in the input ranges, including their end iterators.
Parameters
first, last    the range of elements to apply the algorithm to 
init    the initial value of the generalized sum 
policy    the execution policy to use. See execution policy for details. 
unary_op    unary FunctionObject that will be applied to each element of the input range. The return type must be acceptable as input to binary_op

binary_op    binary FunctionObject that will be applied in unspecified order to the results of unary_op , the results of other binary_op and init .

Type requirements  
T must meet the requirements of MoveConstructible in order to use overloads (3,6). and the result of the expressions binary_op(init, unary_op(*first)), binary_op(unary_op(*first), init), binary_op(init, init), and binary_op(unary_op(*first), unary_op(*first)) must be convertible to T
 
T must meet the requirements of MoveConstructible in order to use overloads (2,5). and the result of the expressions binary_op1(init, binary_op2(*first1, *first2)), binary_op1(binary_op2(*first1, *first2), init), binary_op1(init, init), and binary_op1(binary_op2(*first1, *first2), binary_op2(*first1, *first2)) must be convertible to T
 
InputIt must meet the requirements of InputIterator.
 
ForwardIt must meet the requirements of ForwardIterator.

Return value
init
and binary_op2(*first,*first2)
, binary_op2(*(first+1),*(first2+1))
, ..., over binary_op1
init
and unary_op(*first)
, unary_op(*(first+1))
, ... unary_op(*(last1))
over binary_op
,where generalized sum GSUM(op, a
1, ..., a
N) is defined as follows:
 if N=1, a
1  if N > 1, op(GSUM(op, b
1, ..., b
K), GSUM(op, b
M, ..., b
N)) where
 b
1, ..., b
N may be any permutation of a1, ..., aN and  1 < K+1 = M ≤ N
 b
in other words, the results of unary_op or of binary_op1 may be grouped and arranged in arbitrary order.
Complexity
binary_op1
and binary_op2
.unary_op
and binary_op
.Exceptions
The overloads with a template parameter named ExecutionPolicy
report errors as follows:
 If execution of a function invoked as part of the algorithm throws an exception and
ExecutionPolicy
is one of the three standard policies, std::terminate is called. For any otherExecutionPolicy
, the behavior is implementationdefined.  If the algorithm fails to allocate memory, std::bad_alloc is thrown.
Notes
In the unarybinary overload (3,6), unary_op
is not applied to init
If first == last
or first1 == last1
, init
is returned, unmodified
Example
transform_reduce can be used to parallelize std::inner_product:
#include <vector> #include <functional> #include <iostream> #include <numeric> #include <execution> int main() { std::vector<double> xvalues(10007, 1.0), yvalues(10007, 1.0); double result = std::transform_reduce( std::execution::par, xvalues.begin(), xvalues.end(), yvalues.begin(), 0.0 ); std::cout << result << '\n'; }
Output:
10007
See also
sums up a range of elements (function template)  
applies a function to a range of elements (function template)  
(C++17) 
similar to std::accumulate, except out of order (function template) 