This SO question引发了关于 std::generate
和标准做出的保证的讨论。特别是,你能否使用具有内部状态的函数对象并依赖于 generate(it1, it2, gen)
来调用 gen()
,将结果存储在 * it
,再调用gen()
,存入*(it + 1)
等,还是可以从后面开始,比如?
标准 (n3337, §25.3.7/1) 是这样说的:
Effects: The first algorithm invokes the function object
gen
and assigns the return value of gen through all the iterators in the range[first,last)
. The second algorithm invokes the function object gen and assigns the return value of gen through all the iterators in the range[first,first + n)
ifn
is positive, otherwise it does nothing.
似乎不能保证顺序,特别是因为其他段落有更强的措辞,例如 std::for_each
(Effects: Applies f
to the result取消引用 [first,last)
范围内的每个迭代器,从 first 开始到 last - 1
。 如果我们按字面意思理解,它仅保证从 first
开始并在 last
结束 - 不保证两者之间的顺序)。
但是:两者都是Microsoft's和 Apache's C++ standard library两者都在其文档页面上提供了示例,这些示例要求评估是连续的。 libc++(在 algorithm
中)和 libstdc++(在 bits/STL_algo.h
中)都是以这种方式实现的。此外,如果没有此保证,您将失去很多潜在的 generate
应用程序。
当前的措辞是否暗示顺序性?如果不是,这是委员会成员的疏忽还是故意的?
(我很清楚,没有多少人能够在不只是推测或讨论的情况下就这个问题提供有见地的答案,但在我看来,按照 SO 指南,这并不会使这个问题“不具有建设性”。 )
感谢@juanchopanza 指出这个问题并让我引用有关 for_each
的段落。
最佳答案
在讨论LWG475 , std::for_each
与 std::transform
进行比较。请注意,“transform
不保证调用其函数对象的顺序”。所以,是的,委员会知道标准中缺乏顺序保证。
对于非顺序行为也没有相反的要求,因此 Microsoft 和 Apache 可以自由使用顺序评估。
关于C++标准写法: Does "through all iterators in the range" imply sequentiality?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24346441/