有人可以告诉我以下的例子:
1)Lambda按值捕获x
。 y
作为参考。如果未指定,其余的默认值是什么?
2)Lambda按值捕获x
。 y
引用,其他所有值。
3)Lambda按值捕获x
。 y
引用,其他所有参考文献。
此外,允许同一范围内的2个lambda具有相同的捕获签名,例如两者都是[]
,或者两者都是[& x,=]
由于
答案 0 :(得分:11)
1)未捕获[x, &y](){}
休息
2)[=, &y](){}
3)[&, x](){}
捕获列表是以逗号分隔的零个或多个捕获列表, 可选地以capture-default开头。唯一的捕获 默认值是& (通过引用)和=(按值)。如果是捕获默认值 如果使用,其他任何捕获都不能使用相同的捕获类型。任何捕获 可能只出现一次。
此外,是否允许同一范围内的2个lambda具有相同的捕获签名,例如两者都是[],或者两者都是[& x,=]
当然是允许的。每个lambda都是不同的对象,并且具有不同的类型。如果你在两个lambda中按值捕获变量,那么每个lambda都有它的副本。如果您通过引用在两个lambda中捕获变量,那么每个lambda将引用相同的捕获变量。
答案 1 :(得分:7)
可以写一些例子:
int x = 7, y = 12, z = 24;
auto lambda1 = [x, &y]{
// can't do this...
// std::cout << "x=" << x << ", y=" << y << ", z=" << z << std::endl;
std::cout << "x=" << x << ", y=" << y << std::endl;
};
auto lambda2 = [=, x, &y]{
std::cout << "x=" << x << ", y=" << y << ", z=" << z << std::endl;
};
auto lambda3 = [&, x, &y]{
std::cout << "x=" << x << ", y=" << y << ", z=" << z << std::endl;
};
++x, ++y, ++z;
lambda1();
lambda2();
lambda3();
现在,lambda1
此处无法使用z
。没有&#34;隐含&#34;捕获,因为我们没有指定=
或&
且z
没有出现在捕获列表中,我们无法在那里打印z
。如果我们试图使用我已注释掉的那条线,那就错了。
另外两个很好,分别打印7,13,24和7,13,25。请注意,=
和&
必须先行。此外,鉴于我们通过值/引用捕获所有内容,其他捕获之一是多余的,因此我们可以完成:
auto lambda2 = [=, &y]{ ... };
auto lambda3 = [&, x]{ ... };
答案 2 :(得分:2)
1)
[x,&y](){} // the rest is not captured, eg `z` is not defined in the scope
2)
[=,&y](){} // `=` is capture everything by value
3)
[&,x](){} // `&` is capture everything by reference
答案 3 :(得分:1)
从他的C++11 FAQ:
中引用Bjarne[&amp;]是一个&#34;捕获列表&#34;指定使用的本地名称将通过引用传递。我们本可以说我们想要捕捉&#34;只有v,我们可以这么说:[&amp; v]。如果我们想通过值传递v,我们可以这么说:[= v]。什么都不捕获[],通过引用捕获全部是[&amp;],并且按值捕获全部是[=]。 如果一个动作既不常见也不简单,我建议使用一个命名的函数对象或函数。