C ++ lambda的机制是什么?

Hwa*_*n E 1 c++ lambda scope initialization reference

我正在学习lambda。

但是我有一个问题。

#include <iostream>

using namespace std;

int main() {
    int x = 10;

    auto l1 = [&](){
        x = 5;
        return x;
    };

    auto l2 = [&, x = x + 100](){
        return x;   
    };

    cout << l1() << endl;
    cout << "main  x  : " << x << endl;;
    cout << l2() << endl;
    cout << "main  x  : " << x << endl;;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

此代码的输出是:

5
main x : 5
110
main x : 5
Run Code Online (Sandbox Code Playgroud)

为什么这不是输出?

5
main x : 5
105
main x : 5
Run Code Online (Sandbox Code Playgroud)

由于内联,输出会是这样吗?

Vla*_*cow 7

在此lambda声明中

auto l2 = [&, x = x + 100](){
    return x;   
};
Run Code Online (Sandbox Code Playgroud)

您将x在lambda范围内引入一个新变量(数据成员),并通过x + 100其中xmain中声明的局部变量的表达式对其进行初始化。因此原始变量x将不会更改。lambda返回lambda的新变量的值xx在main中声明的局部变量将不会更改。

捕获默认设置&是多余的,因为没有捕获任何变量。

所以lambda可以像

auto l2 = [x = x + 100]{
    return x;   
};
Run Code Online (Sandbox Code Playgroud)

它看起来像是ctor初始化。考虑一下

struct A
{
    const int x;
    A( int x ) : x( x ) {}
                 ^^^^^^
};
Run Code Online (Sandbox Code Playgroud)

在括号内使用局部变量(参数)x。括号外使用数据成员x

在此Lambda上方的Lambda对面

auto l1 = [&](){
    x = 5;
    return x;
};
Run Code Online (Sandbox Code Playgroud)

x通过引用捕获局部变量。结果,它被lambda更改。

至于输出

110
Run Code Online (Sandbox Code Playgroud)

然后在x尚未通过第一个lambda调用更改第二个lambda的定义中使用局部变量。

当定义第二个lambda时,局部变量x被初始化为

int x = 10;
Run Code Online (Sandbox Code Playgroud)

例如,如果您在调用第一个lambda之后插入第二个lambda定义,例如

cout << l1() << endl;
cout << "main  x  : " << x << endl;;

auto l2 = [x = x + 100]{
    return x;   
};
Run Code Online (Sandbox Code Playgroud)

那么你会得到输出

5
main  x  : 5
105
main  x  : 5
Run Code Online (Sandbox Code Playgroud)