由于在c++17中没有基于索引的并行算法,我想知道是否可以结合使用来模拟它。那是:ranges::view::iota
std::for_each
using namespace std;
constexpr int N= 10'000'000;
ranges::iota_view indices(0,N);
vector<int> v(N);
for_each(execution::par_unseq,indices.begin(),indices.end(),[&](int i) { v[i]= i; });
iota_view
似乎为适当的类型([range.iota.iterator])提供随机访问:
iota_view<I, Bound>::iterator::iterator_category
定义如下:(1.1) — 如果
I
模型Advanceable
,那么iterator_category
是random_access_iterator_tag
。(1.2) — 否则,如果
I
模型Decrementable
,iterator_category
则为bidirectional_iterator_tag
。(1.3) — 否则,如果
I
模型Incrementable
,iterator_category
则为forward_iterator_tag
。(1.4) — 否则,
iterator_category
是input_iterator_tag
。
上面的代码正确吗?iota_view
使用这种方式是否有任何性能损失?
编辑:我用range-v3、cmcstl2和 Intel 的PSTL做了一些测试。
使用 range-v3,上面的示例无法使用 GCC 8 编译。编译器抱怨begin
并end
具有不同的类型:
deduced conflicting types for parameter ‘_ForwardIterator’ (‘ranges::v3::basic_iterator<ranges::v3::iota_view<int, int> >’ and ‘ranges::v3::default_sentinel’)
使用 cmcstl2 代码可以干净地编译,但不能并行运行。在我看来,它回退到顺序版本,可能是因为不满足前向迭代器的要求(https://godbolt.org/z/yvr-M2)。
有一个有点相关的 PSTL 问题(https://github.com/intel/parallelstl/issues/22)。