std算法和副作用的并行实现

blu*_*rni 8 c++ algorithm c++11

通过标准文档std::transform,我注意到在C++ 11之前,仿函数参数不需要有副作用,而从C++ 11开始,要求的限制性较小 - "op和binary_op不会使迭代器失效或子范围,或修改范围中的元素".看到

http://en.cppreference.com/w/cpp/algorithm/transform

和标准的第25.3.4节.cppreference.com上的网页还提到"这些要求的目的是允许并行或无序实现std::transform".

我不明白这段代码在C++ 11中是否合法:

std::vector<int> v(/* fill it with something */), v_transformed;
int foo = 0;
std::transform(v.begin(),v.end(),std::back_inserter(v_transformed),[&foo](const int &n) -> int {
    foo += 1;
    return n*2;
});
Run Code Online (Sandbox Code Playgroud)

显然,如果std::transform在幕后并行化,我们将有多个并发调用foo += 1,这将是UB.但是仿函数本身似乎并没有违反标准中列出的要求.

这个问题可以被要求用于其他标准算法(除了我认为std::for_each,它明确指出迭代将按顺序执行).

我误解了什么吗?

MWi*_*Wid 3

据我了解 C++11 规范,所有标准库函数都必须按顺序执行所有操作(如果它们的效果对用户可见)。特别是,所有“变异序列操作”必须按顺序执行。

\n\n

标准的相关部分是 \xc2\xa717.6.5.9/8:

\n\n
\n

除非另有说明,C++ 标准库函数应仅在当前线程内执行所有操作,前提是这些操作具有用户可见的效果 (1.10)。

\n
\n