当我写了拉姆达[=]
这是否意味着我的所有局部变量将被复制到所创建的结构成员或者我可以假设其在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;
});
}
以下哪项,如果有的话,是真的吗?
- 这两个N和V将被复制
- n将被复制,V不会
- n将被复制,V可以或可以不依赖于implmenentation /优化设置复制。
假设该参数的缘故是矢量的拷贝构造函数有副作用。
不,它只是意味着从环境范围内的所有局部变量可用于拉姆达的身体里面查找。 只有当你是指环境局部变量的名称将变量被捕获,它会通过值捕获。
在“捕获任何”速记=
和&
只是语法糖,本质上,告诉编译器“弄清楚我的意思。”
从5.1.2 / 11-12的正式参考:
如果λ-表达具有相关联捕捉默认及其化合物语句 ODR用途[...]与自动存储持续时间和ODR使用的实体的变量没有明确地捕获,然后在ODR使用的实体到所述被隐式捕获 [...]
如果是显式或隐式捕获的实体被捕获 。
需要注意的是“ 捕获默认 ”是指[=]
和[&]
。 要重复,指定捕获默认没有捕获任何东西; 仅ODR-使用可变一样。
没有! (谢天谢地)
你可以检测你自己的代码来检查你的编译器是否真的做它(或没有)。 例如GCC 4.8.0似乎是兼容的。
至于什么标准强制要求实际(向后工作):
§5.1.2/ 14的实体是通过拷贝捕获 ,如果它是隐式捕捉和俘获-默认为=
或者如果它明确地用捕获捕获的不包括&
。 对于由复制捕获的每个实体,未命名的非静态数据成员在闭合类型声明。
$ 5.1.2 / 11如果λ-表达具有相关联捕捉默认及其化合物语句ODR用途(3.2) this
或可变具有自动存储持续时间和ODR使用的实体没有明确地捕获, 则odr-用过的实体被认为是隐式地捕获 ; 这样的实体应lambda表达式的到达范围中声明。
§5.1.2/ 9所述的λ-表达式,其最小包围范围是块范围(3.3.3)是本地lambda表达式; 任何其他拉姆达表达式不得有捕获列表中的λ-介绍人。 本地lambda表达式的到达范围设定封闭范围高达并包括最内层的功能和它的参数。 [注意:此到达范围包括任何中间的λ表达式。 末端注]