lambda捕获什么都不能访问全局变量?

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体中使用的所有自动变量,如果存在,则通过引用捕获当前对象
  • []什么也没捕捉到


Sou*_*nti 7

默认访问全局、​​静态和常量变量:

#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)