Can you modify temporary intermediate values from transform step in std::transform_reduce?

Viewed 57

Is it UB to modify temporary intermediate values in std::transform_reduce?

Suppose I want to merge lists in parallel and reuse some of the memory. I could try to use std::transform_reduce for that:

#include <list>
#include <vector>
#include <numeric>
#include <execution>
#include <iostream>

using namespace std;

list<int> list_merge(const vector<list<int>> &lists)
{
    auto merge_binary_op = [](auto &&list1, auto &&list2)
    {
        list1.splice(list1.end(), list2);
        return std::move(list1);
    };
    auto copy_list_unary_op = [](const list<int> &list_to_copy)
    {
        return list_to_copy;
    };

    return transform_reduce(execution::par, lists.begin(), lists.end(), list<int>{}, merge_binary_op, copy_list_unary_op);
}

int main()
{
    auto lists = vector<list<int>>{{1}, {2, 3}, {4, 5, 6}};
    for (auto &el : list_merge(lists))
        cout << el << ' ';
    cout << endl;
}

https://godbolt.org/z/r44vfM978

The standard seems to prohibit only modification of the initial values. However, std::reduce effectively prohibits binary operations that modify its arguments. I wonder if it's UB what I do since it seems to go against the spirit of Parallelism TS. Could the standard authors have just copied the wording from std::reduce to std::transform_reduce?

0 Answers
Related