C++17stladvanced
std::reduce
C++17 · Practical Modern · Compiler flag: -std=c++17
Explanation
Generalized reduction over a range, similar to `std::accumulate` but with relaxed ordering requirements that permit parallel execution. The binary operation must be associative and commutative for correct parallel results.
Real-World Scenario
Compute the total revenue from a large sales dataset using parallel reduction.
Quick Snippet
snippet.cpp
#include <numeric>
#include <vector>
#include <execution>
std::vector<double> sales = {1200.50, 3400.75, 890.25, 5600.00};
double total = std::reduce(std::execution::par, sales.begin(), sales.end(), 0.0);Full Example
reduce.cpp
// CodeNebula - C++17 Example: std::reduce
// Compile: g++ -std=c++17 -Wall -Wextra -o example reduce.cpp
// Demonstrates std::reduce, a parallel-friendly alternative to std::accumulate.
// Unlike accumulate (which is strictly left-to-right), reduce allows the
// operation to be applied in any order, enabling parallel execution.
// The operation must be associative and commutative for correct results.
#include <iostream>
#include <numeric>
#include <vector>
#include <string>
#include <functional>
int main()
{
// ------------------------------------------------------------------
// 1. Basic sum (like accumulate, but parallelizable)
// ------------------------------------------------------------------
std::cout << "=== basic sum ===" << std::endl;
std::vector<int> nums = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int sum = std::reduce(nums.begin(), nums.end()); // default: 0 + addition
std::cout << " reduce(1..10) = " << sum << std::endl;
// ------------------------------------------------------------------
// 2. Sum with explicit initial value
// ------------------------------------------------------------------
std::cout << "\n=== sum with init ===" << std::endl;
int sum_from_100 = std::reduce(nums.begin(), nums.end(), 100);
std::cout << " reduce(1..10, init=100) = " << sum_from_100 << std::endl;
// ------------------------------------------------------------------
// 3. Product using custom operation
// ------------------------------------------------------------------
std::cout << "\n=== product ===" << std::endl;
std::vector<int> factors = {1, 2, 3, 4, 5};
int product = std::reduce(factors.begin(), factors.end(), 1, std::multiplies<>{});
std::cout << " reduce(1..5, init=1, multiply) = " << product << std::endl;
// ------------------------------------------------------------------
// 4. Max element via reduce
// ------------------------------------------------------------------
std::cout << "\n=== max element ===" << std::endl;
std::vector<int> data = {42, 17, 93, 5, 68, 31};
int max_val = std::reduce(data.begin(), data.end(), data.front(),
[](int a, int b) { return a > b ? a : b; });
std::cout << " max of {42,17,93,5,68,31} = " << max_val << std::endl;
// ------------------------------------------------------------------
// 5. Sum of doubles (floating-point reduction)
// ------------------------------------------------------------------
std::cout << "\n=== floating-point sum ===" << std::endl;
std::vector<double> prices = {19.99, 5.49, 12.00, 3.75, 8.25};
double total = std::reduce(prices.begin(), prices.end(), 0.0);
std::cout << " total price = " << total << std::endl;
// ------------------------------------------------------------------
// 6. Comparison: reduce vs accumulate
// ------------------------------------------------------------------
std::cout << "\n=== reduce vs accumulate ===" << std::endl;
// For associative+commutative ops, results match
int acc_sum = std::accumulate(nums.begin(), nums.end(), 0);
int red_sum = std::reduce(nums.begin(), nums.end(), 0);
std::cout << " accumulate: " << acc_sum << std::endl;
std::cout << " reduce : " << red_sum << std::endl;
std::cout << " equal : " << std::boolalpha << (acc_sum == red_sum) << std::endl;
// ------------------------------------------------------------------
// 7. Counting even numbers via reduce
// ------------------------------------------------------------------
std::cout << "\n=== count evens via reduce ===" << std::endl;
std::vector<int> values = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int even_count = std::reduce(values.begin(), values.end(), 0,
[](int count, int val) { return count + (val % 2 == 0 ? 1 : 0); });
// Note: this only works correctly with sequential execution since
// the lambda is not commutative. For parallel, use transform_reduce.
std::cout << " even numbers in 1..10: " << even_count << std::endl;
return 0;
}
/*
Expected output:
=== basic sum ===
reduce(1..10) = 55
=== sum with init ===
reduce(1..10, init=100) = 155
=== product ===
reduce(1..5, init=1, multiply) = 120
=== max element ===
max of {42,17,93,5,68,31} = 93
=== floating-point sum ===
total price = 49.48
=== reduce vs accumulate ===
accumulate: 55
reduce : 55
equal : true
=== count evens via reduce ===
even numbers in 1..10: 5
*/
Run command
g++ -std=c++17 -Wall -Wextra -o example reduce.cpp