xml*_*lmx 19 c++ lambda standards global-variables c++11
int n;
int main()
{
[](){ n = 0; }(); // clang says "ok"
int m;
[](){ m = 0; }(); // clang says "not ok"
}
Run Code Online (Sandbox Code Playgroud)
我只是好奇:
如果lambda没有捕获任何内容,是否允许按照C++标准访问全局变量?
Igo*_*nik 16
是的,当然.正常的名称查找规则适用.
[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是不是,所以不必.
Jia*_*Cai 10
实际上[](){ n = 10; }();它没有捕获任何东西,而是使用全局变量.
int n;
int main()
{
[](){ n = 10; }(); // clang says "ok"
std::cout << n; // output 10
}
Run Code Online (Sandbox Code Playgroud)
请参阅解释中的捕获列表
capture-list - 以逗号分隔的零个或多个捕获列表,可选地以capture-default开头.
捕获列表可以如下传递(详细说明见下文):
- [a,&b]其中a由副本捕获,b通过引用捕获.
- [this]通过引用捕获当前对象(*this)
- [&]通过引用捕获lambda体中使用的所有自动变量,如果存在,则通过引用捕获当前对象
- [=]通过复制捕获lambda体中使用的所有自动变量,如果存在,则通过引用捕获当前对象
- []什么也没捕捉到
默认访问全局、静态和常量变量:
#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; }();
}
Run Code Online (Sandbox Code Playgroud)