我被告知here:
无法保证生成的顺序=>取决于实施
我查了gcc's implementation of generate
:
for (; __first != __last; ++__first)
*__first = __gen();
Visual Studio的实现与此完全相同。这对我来说是一种解脱,因为在generate
中使用lambda来读取和写入捕获可能会产生不确定的结果:
int foo[] = {1, 0, 13};
vector<int> bar(3);
generate(bar.begin(), bar.end(), [&]() {
static auto i = 0;
static auto total = 0;
total += foo[i];
return foo[i] / total;
});
I expect bar
包含{1, 0, 0}
。
如果我被允许不按顺序执行,这甚至可能导致除以0错误。
如果可以通过证明generate
需要按顺序执行来回答这个问题,那么我会更容易入睡。
作为一个注释,我知道experimental::parallel::generate
不会是连续的。我只是询问generate
。
答案 0 :(得分:3)
我对此很感兴趣所以做了一些研究。
本回答的底部是2011年标准相关部分的副本。
您将从std::generate<>
的模板声明中看到,迭代器参数必须分别符合ForwardIterator
和OutputIterator
的概念。
ForwardIterator 不支持随机访问。它只能按顺序读取或写入。 OutputIterator
更具限制性 - 其operator*
隐含地包含operator++
的效果。这是该概念的一个明确特征。
因此,暗示,此函数的实现必须顺序访问元素(因此顺序生成值),因为不这样做会破坏接口中隐含的契约
因此标准 (隐式且安静地)保证std::generate
按顺序初始化其元素。编写一个格式良好的std::generate
实现是不可能的。
QED
25.3.7生成[alg.generate]
template<class ForwardIterator, class Generator>
void generate(ForwardIterator first, ForwardIterator last,
Generator gen);
template<class OutputIterator, class Size, class Generator>
OutputIterator generate_n(OutputIterator first, Size n, Generator gen);
1效果:第一个算法调用函数对象gen和 通过范围内的所有迭代器分配gen的返回值 [第一,最后一个)。第二个算法调用函数对象gen和 通过范围内的所有迭代器分配gen的返回值 [first,first + n)如果n是正数,否则它什么都不做。
2 要求:gen不带参数,大小可以转换为 积分型(4.7,12.3)。
3返回:generate_n返回第一个+ n n的非负值和负值的第一个。
4复杂性: 完全是最后的 - 第一次,第n次或0次调用gen和赋值, 分别
答案 1 :(得分:1)
以下是关于它的所有标准(25.7.3 / 1):
template<class ForwardIterator, class Generator>
void generate(ForwardIterator first, ForwardIterator last, Generator gen);
template<class OutputIterator, class Size, class Generator>
OutputIterator generate_n(OutputIterator first, Size n, Generator gen);
第一个算法调用函数对象 根 并指定返回值 根 通过 范围内的所有迭代器 [第一,最后一个) 。第二种算法调用函数对象 根 并指定返回值 根 通过范围内的所有迭代器 [第一,第一+ n) 如果 ñ 是 积极的,否则它什么都不做。
如您所见,未明确声明迭代器分配必须按顺序完成。