Daily bit(e) C++. std::transform_reduce

Добавлено 12 августа 2026 в 07:32

Daily bit(e) C++ 68, обобщенный алгоритм преобразования и редукции в C++17: std::transform_reduce.

Daily bit(e) C++

Преобразование-редукция – распространенная операция в распределенных системах. В C++17 была добавлена поддержка одноименного алгоритма, предлагающего шаблон преобразования-редукции для диапазонов.

Данный алгоритм требует коммутативной и ассоциативной редукции, но предлагает варианты с одним и двумя диапазонами, а также параллельные перегрузки.

#include <numeric>
#include <vector>
#include <execution>

std::vector<double> values{2.3, 9.1, 4.7, 7.1, 1.9, 5.2};
std::vector<double> predictions{1.0, 2.0, 3.0, 4.0, 5.0, 6.0};

// Вычислить среднеквадратичную ошибку:
auto mse = std::transform_reduce(
    values.begin(), values.end(), // все элементы
    predictions.begin(),          // первый элемент из второго диапазона
    0.,          // начальное значение также определяет тип аккумулятора
    std::plus<>{},                // операция редукции
    [](double val, double pred) { // операция преобразования
        return (val-pred)*(val-pred);
    }) / values.size();           // вычислить среднее значение

// То же самое, но вычисляемое параллельно.
auto mse_par = std::transform_reduce(
    std::execution::par_unseq,
    values.begin(), values.end(),
    predictions.begin(), 
    0.,
    std::plus<>{},
    [](double val, double pred) {
        return (val-pred)*(val-pred); 
    }) / values.size();

// mse == mse_par == 12.475

std::vector<int> data{1,2,3,4,5};
// Унарная (для одного диапазона) версия также поддерживается:
int sum_of_squares = std::transform_reduce(data.begin(), data.end(),
    0,
    std::plus<>{},
    [](int v) { return v*v; });
// sum_of_squares == 55

Пример на Compiler Explorer

Теги

C++ / CppDaily bit(e) C++Программирование