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, T init, BinaryOp1 binary_op1, BinaryOp2 binary_op2);  (2)  (since C++17) 
template<class InputIt, class T, class BinaryOp, class UnaryOp> T transform_reduce(InputIt first, InputIt last, T init, BinaryOp binop, UnaryOp unary_op);  (3)  (since C++17) 
template<class ExecutionPolicy, class ForwardIt1, class ForwardIt2, class T> T transform_reduce(ExecutionPolicy&& policy, ForwardIt1 first1, ForwardIt1 last1, ForwardIt2 first2, T init);  (4)  (since C++17) 
template<class ExecutionPolicy, class ForwardIt1, class ForwardIt2, class T, class BinaryOp1, class BinaryOp2> T transform_reduce(ExecutionPolicy&& policy, ForwardIt1 first1, ForwardIt1 last1, ForwardIt2 first2, T init, BinaryOp1 binary_op1, BinaryOp2 binary_op2);  (5)  (since C++17) 
template<class ExecutionPolicy, class ForwardIt, class T, class BinaryOp, class UnaryOp> T transform_reduce(ExecutionPolicy&& policy, ForwardIt first, ForwardIt last, T init, BinaryOp binary_op, UnaryOp unary_op);  (6)  (since C++17) 
transform_reduce(first1, last1, first2, init, std::plus<>(), std::multiplies<>());
, effectively parallelized version of the default std::inner_product
binary_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.
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 LegacyInputIterator. 

ForwardIt must meet the requirements of LegacyForwardIterator. 
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:
in other words, the results of unary_op or of binary_op1 may be grouped and arranged in arbitrary order.
binary_op1
and binary_op2
.unary_op
and binary_op
.The overloads with a template parameter named ExecutionPolicy
report errors as follows:
ExecutionPolicy
is one of the standard policies, std::terminate
is called. For any other ExecutionPolicy
, the behavior is implementationdefined. std::bad_alloc
is thrown. In the unarybinary overload (3,6), unary_op
is not applied to init
.
If first == last
or first1 == last1
, init
is returned, unmodified.
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
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) 
© cppreference.com
Licensed under the Creative Commons AttributionShareAlike Unported License v3.0.
http://en.cppreference.com/w/cpp/algorithm/transform_reduce