Defined in header <numeric>  

template<class InputIt> typename std::iterator_traits<InputIt>::value_type reduce( InputIt first, InputIt last);  (1)  (since C++17) 
template<class ExecutionPolicy, class ForwardIt> typename std::iterator_traits<ForwardIt>::value_type reduce( ExecutionPolicy&& policy, ForwardIt first, ForwardIt last);  (2)  (since C++17) 
template<class InputIt, class T> T reduce(InputIt first, InputIt last, T init);  (3)  (since C++17) 
template<class ExecutionPolicy, class ForwardIt, class T> T reduce(ExecutionPolicy&& policy, ForwardIt first, ForwardIt last, T init);  (4)  (since C++17) 
template<class InputIt, class T, class BinaryOp> T reduce(InputIt first, InputIt last, T init, BinaryOp binary_op);  (5)  (since C++17) 
template<class ExecutionPolicy, class ForwardIt, class T, class BinaryOp> T reduce(ExecutionPolicy&& policy, ForwardIt first, ForwardIt last, T init, BinaryOp binary_op);  (6)  (since C++17) 
reduce(first, last, typename std::iterator_traits<InputIt>::value_type{})
reduce(first, last, init, std::plus<>())
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
is not associative or not commutative.
The behavior is undefined if binary_op
modifies any element or invalidates any iterator in [first; last], including the end iterator.
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. 
binary_op    binary FunctionObject that will be applied in unspecified order to the result of dereferencing the input iterators, the results of other binary_op and init . 
Type requirements  
InputIt must meet the requirements of LegacyInputIterator. 

ForwardIt must meet the requirements of LegacyForwardIterator. 

T must meet the requirements of MoveConstructible. and binary_op(init, *first) , binary_op(*first, init) , binary_op(init, init) , and binary_op(*first, *first) must be convertible to T . 
Generalized sum of init
and *first
, *(first+1)
, ... *(last1)
over binary_op
,
where generalized sum GSUM(op, a
1, ..., a
N) is defined as follows:
in other words, reduce
behaves like std::accumulate
except the elements of the range may be grouped and rearranged in arbitrary order.
O(last  first) applications of 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. If the range is empty, init
is returned, unmodified.
sidebyside comparison between reduce and std::accumulate
:
#include <iostream> #include <chrono> #include <vector> #include <numeric> #include <execution> int main() { std::vector<double> v(10'000'007, 0.5); { auto t1 = std::chrono::high_resolution_clock::now(); double result = std::accumulate(v.begin(), v.end(), 0.0); auto t2 = std::chrono::high_resolution_clock::now(); std::chrono::duration<double, std::milli> ms = t2  t1; std::cout << std::fixed << "std::accumulate result " << result << " took " << ms.count() << " ms\n"; } { auto t1 = std::chrono::high_resolution_clock::now(); double result = std::reduce(std::execution::par, v.begin(), v.end()); auto t2 = std::chrono::high_resolution_clock::now(); std::chrono::duration<double, std::milli> ms = t2  t1; std::cout << "std::reduce result " << result << " took " << ms.count() << " ms\n"; } }
Possible output:
std::accumulate result 5000003.50000 took 12.7365 ms std::reduce result 5000003.50000 took 5.06423 ms
sums up a range of elements (function template) 

applies a function to a range of elements (function template) 

(C++17)  applies a functor, then reduces out of order (function template) 
© cppreference.com
Licensed under the Creative Commons AttributionShareAlike Unported License v3.0.
http://en.cppreference.com/w/cpp/algorithm/reduce