C++基础:lambda介绍以及简述值捕获、引用捕获、隐式捕获的区别以及注意事项

C++11 引入了 lambda 表达式,它是一种定义和使用匿名函数对象的简便方式。Lambda 表达式与普通函数类似,也有参数列表、返回值类型和函数体,只是它的定义方式更简洁,并且可以在函数内部定义。

Lambda 表达式的语法如下:

[capture] (parameters) -> return_type { function_body }

其中:

  • capture 是捕获列表,它指定了哪些外部变量可以在 lambda 函数体内使用。
  • parameters 是参数列表,与普通函数的参数列表类似。
  • return_type 是返回值类型,可以省略,由编译器推断。
  • function_body 是函数体,包含了 lambda 函数的具体逻辑。

首先看一下这个面试题

    int v = 19;
    auto f1 = [v]{return v;};  // 值捕获
    auto f2 = [=]{return v;}; // 隐式捕获值

    auto f3 = [&v]{return v;}; // 引用捕获
    auto f4 = [&]{return v;};  // 隐式捕获引用

    v = 10;
    std::cout << f1() << " " << f2()  << " " << f3() << " " << f4() << std::endl;

此题输出结果是 19 19 10 10
引用捕获传递的是引用,后边值修改后引用也会改变,值捕获传递的是此时此刻的值,后续做的修改不影响当前值

捕获列表中可以指定值捕获、引用捕获和隐式捕获三种方式:

  • 值捕获:以值的方式捕获外部变量,在 lambda 函数内部使用的是外部变量的副本。例如 [x] 表示以值的方式捕获外部变量 x。下面是一个例子:
#include <iostream>
int main() {
    int x = 10;
    auto f = [x]() { std::cout << x << std::endl; };
    x = 20;
    f(); // 输出 10
    return 0;
}

在上面的代码中,我们以值的方式捕获了外部变量 x,并在 lambda 函数内部输出它的值。由于是以值的方式捕获,所以即使后面修改了 x 的值,lambda 函数内部仍然使用的是原来的值。

  • 引用捕获:以引用的方式捕获外部变量,在 lambda 函数内部使用的是外部变量本身。例如 [&x] 表示以引用的方式捕获外部变量 x。下面是一个例子:
#include <iostream>
int main() {
    int x = 10;
    auto f = [&x]() { std::cout << x << std::endl; };
    x = 20;
    f(); // 输出 20
    return 0;
}

在上面的代码中,我们以引用的方式捕获了外部变量 x,并在 lambda 函数内部输出它的值。由于是以引用的方式捕获,所以当后面修改了 x 的值时,lambda 函数内部也会使用新的值。

  • 隐式捕获:可以使用 & 或 = 来指定隐式捕获所有外部变量。例如 [&] 表示以引用的方式隐式捕获所有外部变量,[=] 表示以值的方式隐式捕获所有外部变量。下面是一个例子:
#include <iostream>
int main() {
    int x = 10, y = 20;
    auto f1 = [&]() { std::cout << x << " " << y << std::endl; };
    auto f2 = [=]() { std::cout << x << " " << y << std::endl; };
    x = 30; y = 40;
    f1(); // 输出 30 40
    f2(); // 输出 10 20
    return 0;
}

在上面的代码中,我们分别使用隐式引用捕获和隐式值捕获定义了两个 lambda 函数。当后面修改了 x 和 y 的值时,第一个 lambda 函数输出新的值,而第二个 lambda 函数输出原来的值。

需要注意的是,在使用引用捕获时,要确保被引用的对象在 lambda 表达式执行时仍然存在。此外,在 lambda 函数中修改值捕获的非静态局部变量时,需要在参数列表后面加上 mutable 关键字。

Lambda 表达式非常灵活强大,但也有一些需要注意的问题。例如,

  1. 在多线程环境中使用引用捕获时要注意线程安全问题;
  2. 在使用隐式捕获时要注意不要意外地捕获了不需要的变量;
  3. 在使用值捕获时要注意被捕获的变量是否可以拷贝等。
    总之,在使用 lambda 表达式时要仔细考虑各种情况,避免出现意料之外的问题。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

telllong

你的鼓励是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值