C ++ lambda的机制是什么?

时间:2019-07-26 10:57:51

标签: c++ lambda scope reference initialization

我正在学习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

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

1 个答案:

答案 0 :(得分:7)

在此lambda声明中

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

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