~ C++17
template<class InputIt>
typename std::iterator_traits<InputIt>::value_type reduce(InputIt first, InputIt last); //constexpr since C++20
tempate<class ExecutionPolicy, class ForwardIt>
typename std::iterator_traits<ForwardIt>::value_type reduce(ExecutionPolicy&& policy, ForwardIt first, Forwardit last);
template<class InputIt, class T>
T reduce(InputIt first, InputIt last, T init); // constexpr since C++20
template<class ExecutionPolicy, class ForwardIt, class T>
T reduce(ExecutionPolicy&& policy, ForwardIt first, ForwardIt last, T init);
template<class InputIt, class T, class BinaryOp>
T reduce(InputIt first, InputIt last, T init, BinaryOp op); // constexpr since C++20
template<class ExecutionPolicy, class ForwardIt, class T, class BinaryOp>
T reduce(ExecutionPolicy&& policy, ForwardIt first, ForwardIt last, T init, BinaryOp op);
: 범위에 있는 요소들을 하나의 값으로 축소(reduce)하는 데 사용됩니다.
실행 정책은 std::execution 헤더에 포함되어있습니다.
- execution::seq : 순차 실행 (기본 값)
- execution::par : 병렬 실행 (멀티코어 시스템에서 작업이 병렬로 수행됩니다.)
- execution::par_unseq : 병렬 및 비순차 실행
<example>
#include <iostream>
#include <numeric>
#include <vector>
using namespace std;
int main() {
vector<int> vec = {1, 2, 3, 4, 5};
int mult = reduce(vec.begin(), vec.end(), 1, [](int a, int b) {return a * b;});
cout << mult;
return 0;
}
결과값
accumulate와 reduce 모두 시퀀스의 요소들을 하나로 합치는 함수입니다.
accumulate : 왼쪽부터 순차적으로 누적합니다.
reduce : 병렬화를 지원하여 더 빠른 계산을 할 수 있습니다.
다만, 병렬화로 인해 순서를 보장하지 않기 때문에 결합 법칙과 교환 법칙이 만족되지 않는다면 예상하지 못한 값을 반환받을 수 있습니다.
만약 op를 [](int a, int b) {return a - b;}처럼 빼기 연산을 사용한다면,
accumulate는 (((a - b) - c) - d)처럼 왼쪽부터 계산을 하는 반면
병렬화 reduce는 ((a - b) - (c - d))처럼 순서를 보장하지 않습니다.
a = 10, b = 5, c = 2, d = 1
accumulate 계산 결과 : 2
병렬화 reduce 계산 결과 : 4 (예시일 뿐, 4가 나온다고 보장할 수 없습니다.)