当我用[=]
写一个lambda时,是否意味着我所有的局部变量都将被复制到创建的struct的成员中,或者我可以假设只有那些实际上在lambda中使用的那些?例如:
void f()
{
vector<int> v(10000);
const int n = 5;
const int DivByNCnt = count_if(istream_iterator<int>(cin), istream_iterator<int>(),
[=](int i)
{
return i % n == 0;
});
}
以下哪项是真的?
假设为了论证,vector的复制构造函数有副作用。
答案 0 :(得分:63)
没有。它只是意味着来自环境范围的所有局部变量都可用于在lambda体内查找。只有 if 你引用环境局部变量的名称才能捕获该变量,并且它将被值捕获。
“捕获任何东西”的缩写=
和&
只是语法糖,本质上是告诉编译器“弄明白我的意思”。
5.1.2 / 11-12的正式参考:
如果lambda表达式具有关联的 capture-default 且其复合语句 odr-使用具有自动存储持续时间和odr的变量 - 未明确捕获使用过的实体,然后使用odr使用的实体隐式捕获 [...]
如果实体是捕获,如果它是显式或隐式捕获的。
请注意,“ capture-default ”指的是[=]
和[&]
。要重复,指定捕获默认值不会捕获任何内容;只有使用变量的odr。
答案 1 :(得分:22)
没有! (谢天谢地)
您可以检测代码以检查编译器是否实际执行了(或不执行)。例如,gcc 4.8.0似乎符合要求。
关于标准实际要求的内容(向后工作):
§5.1.2/ 14如果隐式捕获并且捕获默认值为
=
,或者如果使用不捕获的捕获显式捕获实体,则捕获实体包括&
。对于由副本捕获的每个实体,在闭包类型中声明一个未命名的非静态数据成员。$ 5.1.2 / 11如果lambda表达式具有关联的capture-default及其compound-statement odr-uses(3.2)
this
或具有自动存储持续时间的变量且odr-used实体不是明确捕获,然后然后使用odr使用的实体被隐式捕获;这些实体应在lambda表达式的范围内声明。§5.1.2/ 9 lambda表达式是一个局部lambda表达式,其最小的封闭范围是块作用域(3.3.3);任何其他lambda-expression在其lambda-introducer中都不应该有一个capture-list。本地lambda表达式的到达范围是封闭范围的集合,包括最里面的封闭函数及其参数。 [注意:这个范围包括任何介入的lambda表达式。 - 后注]