C++ lambda的机制是什么?

What is the mechanism of C++ lambda?

我正在研究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;
}

这段代码的输出是:

5
main x : 5
110
main x : 5

为什么不是这个输出?

5
main x : 5
105
main x : 5

因为内联,输出会是这样吗?

在这个 lambda 的声明中

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

您正在 lambda 范围内引入一个新变量(数据成员)x 并通过表达式 x + 100 对其进行初始化,其中 x 是在 main 中声明的局部变量.所以原来的变量x不会改变。 lambda returns lambda 的新变量x 的值。 main中声明的局部变量x不会改变。

捕获默认值 & 是多余的,因为两个变量都没有被捕获。

所以 lambda 可以像这样重写

auto l2 = [x = x + 100]{
    return x;   
};

它看起来与 ctor 初始化类似。考虑例如

struct A
{
    const int x;
    A( int x ) : x( x ) {}
                 ^^^^^^
};

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

与这个lambda上面的lambda相反

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

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

至于输出

110

然后在第二个 lambda 的定义中使用了局部变量 x,当时它还没有被第一个 lambda 的调用改变。

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

int x = 10;

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

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

auto l2 = [x = x + 100]{
    return x;   
};

然后你会得到输出

5
main  x  : 5
105
main  x  : 5