如何让TBB parallel_for_each与std::views::zip实现读写协同?
解决std::views::zip适配tbb::parallel_for_each的读写问题
问题出在TBB对C20视图的适配性上:std::views::zip返回的视图元素是带引用的tuple,但旧版本TBB的parallel_for_each不支持C20 range概念,会把tuple当成值类型拷贝传递,导致你拿到的是副本而非原元素的引用。而标准库的std::ranges::for_each完全适配C++20标准,所以能正常修改元素。
给你几个可行的解决办法:
1. 升级到支持C++20 ranges的TBB版本
TBB从2021.5版本开始正式支持C++20 range,升级后parallel_for_each会自动正确处理std::views::zip返回的引用元素,不需要额外修改代码。
2. 显式用引用捕获元素
如果暂时没法升级TBB,在仿函数里用auto&&接收元素,再通过结构化绑定拿到原容器元素的引用,避免拷贝:
#include <tbb/parallel_for_each.h> #include <ranges> #include <vector> int main() { std::vector<int> src = {1,2,3,4}; std::vector<int> dest(src.size()); tbb::parallel_for_each( std::views::zip(src, dest), [](auto&& elem) { // 用auto&&确保拿到引用 auto& [src_val, dest_val] = elem; // 结构化绑定到引用 dest_val = src_val * 2; // 直接修改dest的元素 } ); return 0; }
3. 手动用TBB的range包装视图
如果上面的方法还是不行,把std::views::zip的结果用tbb::make_range包装,强制TBB使用视图的原生迭代器,确保解引用返回引用:
auto zip_view = std::views::zip(src, dest); tbb::parallel_for_each( tbb::make_range(zip_view.begin(), zip_view.end()), [](auto&& elem) { auto& [s, d] = elem; d = s + 1; } );
核心逻辑就是让TBB的parallel_for_each能正确识别并传递std::views::zip元素的引用,而不是拷贝整个tuple。
内容的提问来源于stack exchange,提问作者rubenvb
相关产品推荐
相关产品推荐

