首页 > 代码库 > C++中的lambda表达式

C++中的lambda表达式

1.基本形式:

[捕获列表](参数列表){函数体};     其中捕获列表和函数体不能省略但是捕获列表可以为空,也就是说最简单的lambda表达式是:  []{};

2.lambda表达式又叫匿名函数,即没有函数名的函数,C++中,一个lambda表达式表示一个可调用的代码单元。我们可以将其理解为一个未命名的内联函数,特别注意,它的返回值类型由函数体中的return语句决定.因此一般使用auto关键字来自动推导

3.使用实例

int i=[]{return 1;}();

//i=1,前面部分,[]{return 1;}是一个省略了中间的参数列表的lambda表达式,可以理解为一个匿名的内联函数,后面的()表示函数调用,将函数调用的返回值赋值给变量i

和下面的语句等价:

auto func=[]{return 1;};//lambda表达式作为匿名内联函数指针赋给func指针,注意不捕获时才可以转换为函数指针,即[]捕获参数列表为空

int i=func();//func指针加()表示函数调用,再将返回值赋给变量i

4.捕获列表的使用:

int v=100;

auto func=[v]{return v;};//捕获列表中的参数,必须是前面已经定义的,称为定义参数,与后面的()中的调用参数相对应

cout<<func();//打印100

4.1捕获列表可以捕获多个变量

int a=100,b=200;

auto func=[a,b]{return a+b;};//同时捕获两个变量

int s=func();

4.2捕获列表有引用和传值两种方式,默认是采用传值的,[a,b],传值,[&a,b],a是传引用,b是传值

int a=100,b=200;

auto func=[a,&b]{++b;return a+b;};//因为捕获参数b是传引用,因此可以更改,且更改后的值会在lambda表达式外生效,即该语句过后,b=201,而a是传值,不允许更改,++a,或者a=b;都是报错

int s=func();

4.3使用mutable关键字来修改传值的捕获参数,但是改变后的参数值,不会在lambda表达式外生效

int p=100,q=200;

auto func=[&p,q]()mutable{p++,q++;return p+q;};//因为使用了mutable关键字,因此即使是传值的捕获参数,也可以修改

int s=func();

cout<<p<<endl;//p=101,传引用

cout<<q<<endl;//q=200,虽然使用了mutable可以修改传值的捕获参数,但是不会在lambda表达式外部生效

4.4捕获列表可以用=或者&要捕获所有变量,=表示传值,&表示引用[=,&b]表示除了参数b以外,都是传值,[=a,&]表示除了参数a传值以外,都是传引用,this指针时

int p=100,q=200;

auto func=[&]{q++,p+=2;return p+q;};//[&]表示所有的捕获参数都是传引用,都可修改,特别是需要使用this指针时,更应该如此

//auto func=[=]{return p+q;};//[=]表示所有的捕获参数都是传值,默认就是这样的,不可修改,使用this指针时,在VC平台不报错,在linux平台报错

int s=func();

5.带调用参数的lambda表达式

auto add=[](int a,int b){return a+b;};//int a,int b是调用时传递的参数,放在()中

auto res=add(2,3);//res=5

捕获参数列表和调用参数列表的区别,在于:一个是定义时传递的参数,一个是调用时传递的参数

6.带明确的返回值的lambda表达式:使用->

auto add=[](int v1,int v2)->int {return v1+v2;};//->int 明确表示返回值类型为int,一般情况下,我们都用auto关键字,自动推导

int s=add(10,20);

cout<<s<<endl;//s=30

7.空的lambda表达式:

auto func=[](){};//也是合法的,编译运行都正确

 

C++中的lambda表达式