C++11-Lambda表达式

本文介绍了C++11中的Lambda表达式,包括其基本语法(捕获列表、参数列表、返回类型和函数体),以及如何通过捕获列表使用外部变量。重点讨论了生命周期问题,提醒开发者注意外部变量的生存期以避免潜在错误。
摘要由CSDN通过智能技术生成

目录

1.简介

2.Lambda表达式语义分析

2.1 基本语法

2.2 捕获列表

3.作用

4.使用注意事项

4.1 生命周期问题


1.简介

Lambda表达式是C++11标准引入的一种特征,它提供了一种方便的方式来定义匿名函数。Lambda表达式能够捕捉外部变量并使用它们的函数对象。

labmbda表达式由捕获列表、参数列表、返回类型和函数体组成,其中,参数列表和返回类型可以忽略,但不可以忽略捕获列表和函数体

[捕获列表](参数列表)->返回类型{函数体}

例如: auto f = []{return 1 + 2;}

auto f = [](int x, int y)->int{ return x + y;}

2.Lambda表达式语义分析

2.1 基本语法

[捕获列表](参数列表)->返回类型{函数体}

auto add = [](int a, int b) -> int {
      return a +b;
}

上述代码表示[]捕获列表为空,参数为int a和int b,返回值类型为int,函数体为return a + b的一个匿名函数,一般情况下,编译器可以自动推断出lambda表达式的返回类型,所以我们也可以不指定返回类型。

auto add = [](int a, int b)  {
return a +b;
}

2.2 捕获列表

如果需要在匿名函数内部使用所在函数体内的变量而不想传参,可以使用捕获列表来实现

int c = 12;
int d = 30;
auto add = [c, d](int a, int b) -> int{
      cout << "d = " << d << endl;
      return c;
}

如果在匿名函数内部加入对变量c,d修改的操作,则无法编译通过,因为上述捕获列表是通过值进行传递的,无法进行修改,如果想要对c,d进行修改,需要传入引用:

int c = 12;
int d = 30;
auto add = [&c, &d](int a, int b) -> int{
cout << "d = " << d << endl;
return c;
}

下表是捕获列表的分类

[]

空捕获列表,Lambda不使用所在函数中的变量

[names]

names是一个逗号分隔的名字列表,这些名字都是Lambda所在函数中的变量,例如[a,b,...]。默认情况下,这些变量按值传递,名字前面如果加上了&,则按引用传递。

[&]

隐式捕获列表,lambda函数体内可以使用lambda所在作用范围内所有可见的局部变量(包括lambda所在类的this),并且是引用传递方式

[=]

隐式捕获列表,lambda函数体内可以lambda所在作用范围内所有可见的局部变量(包括lambda所在类的this),并且是值传递方式。

[this]

lambda函数体内可以使用lambda所在类中的成员变量

[a]

将a按值进行传递,函数体内不能修改传递进来的a的拷贝。

[&a]

将a按引用进行传递

[a, &b]

将a按值进行传递,b按引用进行传递

[=, &a, &b]

除a和b按引用进行传递,其他参数都按值进行传递

[&, a, b]

除a和b按值进行传递,其他参数都按引用进行传递

3.作用

通过引入lambda表达式,使得编写匿名函数变得更加简洁和方便,提高了代码的可读性和灵活性。

4.使用注意事项

4.1 生命周期问题

lambda表达式捕获外部变量时需要注意外部变量的生命周期,以避免访问已经销毁的资源。

示例1 正确示例

该示例能够正常运行,Lambda表达式使用了值捕获[=],这意味着Lambda表达式会复制捕获的变量的值,而不是引用它们。这样,即使捕获的变量超出作用域,Lambda表达式中仍然有它们的副本,因此Lambda表达式可以正常访问和使用这些变量的值

示例2 错误示例

这段代码虽然能够正常运行,但是从理论上来说是存在错误的,在test()中定义lambda表达式时捕获的是test()中所有的变量,并按引用的方式进行传递,test()返回之后其变量被销毁,那么fun函数中持有的引用将会是无效的引用,这可能会导致未定义的行为,因此,按引用的方式进行捕获时一定需要注意变量的生命周期,如果在lambda中不需要对捕获变量进行修改可以考虑按值的方式进行捕获。

看看chatgpt是怎么看待这段代码的

示例3 错误示例

这个错误就不用多说了,销毁一个空间之后还继续使用。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值