#include <iostream>
#include <algorithm>
#include <vector>
int main()
{
// Block 1
{
auto inc = []() { int i = 0; return [&]() { return i++; }; }();
std::vector<int> v(10, 10);
std::generate(v.begin(), v.end(), inc);
for (auto i : v) std::cout << i << std::endl;
}
// Block 2
{
auto inc = []() { int i = 0; return [&]() { return i++; }; };
std::vector<int> v(10, 10);
std::generate(v.begin(), v.end(), inc());
for (auto i : v) std::cout << i << std::endl;
}
}
我不确定为什么这两个块会产生不同的结果。
Block 1: 32767 ... 32776
Block 2: 0 ... 10
对于std::generate
,生成器(inc
)按值传递,所以我相信它应该没问题,对吧?
我正在运行OS X.
谢谢,
<小时/> 请注意,上述代码的结果未定义,请参阅下文。
答案 0 :(得分:10)
我不确定为什么这两个块会产生不同的结果。
两者都是未定义的行为,所以问题没有实际意义。在任何一种情况下,我们都有一个lambda:
height
auto f = []() { int i = 0; return [&]() { return i++; }; };
返回一个有悬空引用的lambda:f()
在i
调用结束时被销毁。悬挂引用发生时
如果你想用lambda创建一个生成计数器,直接的方法是使lambda变为可变并使用init-capture:
f
generate()
是必需的,因为lambdas默认为generate()
,我们需要直接修改成员auto inc = [i=0]() mutable { return i++; };
。
以上是C ++ 14(由于通用的init-capture)。我们可以通过简单地从内部lambda引用捕获嵌套-lambda结构到按值捕获来在C ++ 11中完成这项工作:
mutable
那是......有点讨厌,但是有效吗?