使用 std::for_each 和 std::views::iota 的并行 for 循环

Urw*_*ald 5 c++ algorithm visual-c++ c++20 std-ranges

我想使用std::views.

为了按顺序运行,代码如下所示:

int main() {

    //pseudo-random numbers

    random_device rd;
    default_random_engine eng(rd());
    uniform_int_distribution<int> distr(0, 100);

    auto r = ranges::views::iota(0, 10);
    vector<double> v(10, 1);
    for_each(r.begin(), r.end(), [&](int i) {v[i] = distr(eng); });
    for (auto&& i : v) cout << i << " "; cout << endl;
}
Run Code Online (Sandbox Code Playgroud)

这很好用。我使用的是标准版本std::for_each(),而不是命名空间中的版本ranges,因为它们没有执行策略。现在是并行版本。唯一的区别:

for_each(execution::par, r.begin(), r.end(), [&](int i) {v[i] = distr(eng); });
Run Code Online (Sandbox Code Playgroud)

MSVC 报错:

error C2338: Parallel algorithms require forward iterators or stronger
Run Code Online (Sandbox Code Playgroud)

我在这里发现了类似的问题:Usingranges::view::iota inparallelalgorithm,我实现了那里提供的解决方案:

    auto r = views::iota(0) | views::take(10);
    vector<double> v(10, 1);
    auto input_range = ranges::common_view(r);

    for_each(execution::par, ranges::begin(input_range), ranges::end(input_range), [&](int i) {v[i] = distr(eng); });
    for (auto&& i : v) cout << i << " "; cout << endl;
Run Code Online (Sandbox Code Playgroud)

但是,我仍然面临错误

error C2338: Parallel algorithms require forward iterators or stronger.
Run Code Online (Sandbox Code Playgroud)

有人知道这个问题是否有解决方案?

康桓瑋*_*康桓瑋 7

of 的迭代器operator*()的返回类型不是引用类型,而是值类型,这使得它不是前向迭代器,而是 C++17 中的输入迭代器。由于 C++17 并行算法需要前向迭代器,因此您不能将其应用于.views::iotaviews::iota

有人知道这个问题是否有解决方案?

已经有一篇论文p2408r4解决了这个问题,因此在采用之前标准中没有简单的解决方案。


fir*_*las 3

p2408现已在C++23中采用。在 MSVC 19.34 (VS 17.4) 或更高版本中,如果打开,代码将编译/std:c++latest/std:c++20也将起作用)。例子