int n;
int main()
{
[](){ n = 0; }(); // clang says "ok"
int m;
[](){ m = 0; }(); // clang says "not ok"
}
我只是好奇:
如果lambda没有捕获任何内容,是否允许按照C ++标准访问全局变量?
是的,当然。正常的名称查找规则适用。
[expr.prim.lambda] / 7 ...出于名称查找的目的...复合语句在lambda表达式的上下文中被考虑。
Re:为什么局部变量的处理方式与全局变量不同。
[expr.prim.lambda] / 13 ...如果一个lambda表达式或函数的实例化调用一般lambda odr的操作员模板 - 使用(3.2)
this
或从其到达范围自动存储持续时间的变量,实体应由lambda表达式捕获。[expr.prim.lambda] / 9一个lambda表达式,其最小的封闭作用域是一个块作用域(3.3.3)是一个本地的lambda表达式......本地lambda表达式的到达范围是一组封闭的作用域,直到并包括最里面的封闭功能及其参数。
在您的示例中,m
是一个变量,具有自lambda到达范围的自动存储持续时间,因此应被捕获。 n
不是,所以不一定。
实际上[](){ n = 10; }();
没有捕获任何东西,它使用全局变量。
int n;
int main()
{
[](){ n = 10; }(); // clang says "ok"
std::cout << n; // output 10
}
capture-list - 以逗号分隔的零个或多个捕获列表,可选地以capture-default开头。
捕获列表可以如下传递(详细说明见下文):
- [a,&b]其中a由副本捕获,b通过引用捕获。
- [this]通过引用捕获当前对象(* this)
- [&]通过引用捕获lambda体中使用的所有自动变量,如果存在,则通过引用捕获当前对象
- [=]通过复制捕获lambda体中使用的所有自动变量,如果存在,则通过引用捕获当前对象
- []什么也没捕捉到
默认情况下访问全局,静态和const变量:
#include <iostream>
int n;
int main()
{
[](){ n = 10; }();
std::cout << n << std::endl;
static int m = 1;
[](){ m = 100; }();
std::cout << m << std::endl;
const int l = 200;
[](){ std::cout << l << std::endl; }();
}