如何用运行时值实现无容器并行std::transform替代普通循环?
用并行std::transform替代索引循环的常规实现方法
需求说明
想要把以下普通索引循环:
std::vector<double> data(n, 0); for(int i = 0; i < n; i++){ data[i] = func(i); }
替换为带并行执行策略的std::transform实现,期望的结构如下:
std::vector<double> data(n, 0); std::transform( std::execution::par_unseq, /*from 0*/, /*to n*/, data.begin(), func);
目标是无需额外容器存储索引,且使用运行时值生成索引序列(而非constexpr值)。
当前解决方案
目前实现方式需要额外创建索引容器并填充,代码如下:
std::vector<size_t> indexes(n, 0); auto indexFillFunc = [&indexes](const size_t &value){ return &value - &indexes[0]; }; std::transform( std::execution::par_unseq, indexes.begin(), indexes.end(), indexes.begin(), indexFillFunc); std::vector<double> data(n, 0); std::transform( std::execution::par_unseq, indexes.begin(), indexes.end(), data.begin(), func);
但该方案需要额外维护索引容器,希望了解更常规的实现方式。
常规实现方法(C++20+)
利用C++20引入的std::views::iota视图,它支持运行时值生成连续整数序列,且无需分配额外内存。结合并行版std::transform即可实现需求:
标准std::transform写法
#include <vector> #include <algorithm> #include <execution> #include <ranges> std::vector<double> data(n, 0); std::transform( std::execution::par_unseq, std::views::iota(0, static_cast<int>(n)).begin(), std::views::iota(0, static_cast<int>(n)).end(), data.begin(), func );
C++20范围版写法(更简洁)
#include <vector> #include <algorithm> #include <execution> #include <ranges> std::vector<double> data(n); std::ranges::transform( std::execution::par_unseq, std::views::iota(0, static_cast<int>(n)), data.begin(), func );
注意事项
- 需确保编译器支持C++20及以上标准,且标准库实现了
std::views::iota和并行执行策略。 - 编译时可能需要链接并行库:比如GCC需添加
-fopenmp或链接libstdc++-parallel,MSVC需链接TBB库。
内容的提问来源于stack exchange,提问作者Gergely Tóth
相关产品推荐
相关产品推荐

