【问题标题】:What is the mechanism of C++ lambda?C++ lambda的机制是什么?
【发布时间】:2019-07-26 10:57:51
【问题描述】:

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

因为inline,输出会是这样吗?

【问题讨论】:

标签: c++ lambda scope reference initialization


【解决方案1】:

在这个 lambda 声明中

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

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

捕获默认&amp; 是多余的,因为两个变量都未被捕获。

所以 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

然后局部变量 x 被用于第二个 lambda 的定义中,但它尚未被第一个 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

【讨论】:

  • 这里&amp;有什么用?
  • @deoncagadoes 它是通过引用对局部变量的默认捕获。您可以在 lambda 中删除它,因为这两个变量都没有被捕获。
  • 抱歉,问题已更改。我想让你再看一遍。
  • @HwanE 我已经回答了你的问题。
  • @Vlad 来自莫斯科 我不知道初始化的变量是 const。谢谢!!
猜你喜欢
  • 1970-01-01
  • 2011-03-02
  • 1970-01-01
  • 1970-01-01
  • 2022-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多