Lambda表达式

C++11中的Lambda表达式用于定义并创建匿名的函数对象,以简化编程工作。首先看一下Lambda表达式的基本构成:

 

 [函数对象参数](操作符重载函数参数)mutable或exception ->返回值{函数体}

① 函数对象参数;

[],标识一个Lambda的开始,这部分必须存在,不能省略。函数对象参数是传递给编译器自动生成的函数对象类的构造函数的。函数对象参数只能使用那些到定义Lambda为止时Lambda所在作用范围内可见的局部变量(包括Lambda所在类的this)。函数对象参数有以下形式:

  • 空         没有使用任何函数对象参数。
  • =           函数体内可以使用Lambda所在作用范围内所有可见的局部变量(包括Lambda所在类的this),并且是值传递方式(相当于编译器自动为我们按值传递了所有局部变量)。
  • &           函数体内可以使用Lambda所在作用范围内所有可见的局部变量(包括Lambda所在类的this),并且是引用传递方式(相当于编译器自动为我们按引用传递了所有局部变量)。
  • this        函数体内可以使用Lambda所在类中的成员变量。
  • a            将a按值进行传递。按值进行传递时,函数体内不能修改传递进来的a的拷贝,因为默认情况下函数是const的。要修改传递进来的a的拷贝,可以添加mutable修饰符。
  • &a          将a按引用进行传递。
  • a, &b      将a按值进行传递,b按引用进行传递。
  • =,&a, &b              除a和b按引用进行传递外,其他参数都按值进行传递。
  • &, a, b                    除a和b按值进行传递外,其他参数都按引用进行传递。
 1     // 1 按值传递,按值传递修改参数记得加mutable
 2     cout<<"*****1*****"<<endl;
 3     int m1 = 0, n1 = 0;
 4     auto f1 = [=](int t)mutable{ cout<<"lambda = "<<(m1 = ++n1 + t)<<endl;};
 5     f1(10);
 6     cout<<"m1 = "<<m1<<endl;
 7     cout<<"n1 = "<<n1<<endl;
 8     cout<<"*****1*****\n"<<endl;
 9 
10     // 2 引用传递
11     cout<<"*****2*****"<<endl;
12     int m2 = 0, n2 = 0;
13     auto f2 = [&](int t){cout<<"lambada = "<<(m2 = ++n2 + t)<<endl;};
14     f2(10);
15     cout<<"m2 = "<<m2<<endl;
16     cout<<"n2 = "<<n2<<endl;
17     cout<<"*****2*****\n"<<endl;
18 
19     // 3 m3引用,其它按值传递
20     cout<<"*****3*****"<<endl;
21     int m3 = 0, n3 = 0;
22     auto f3 = [=, &m3](int t)mutable{cout<<"lambada = "<<(m3 = ++n3 + t)<<endl;};
23     f3(10);
24     cout<<"m3 = "<<m3<<endl;
25     cout<<"n3 = "<<n3<<endl;
26     cout<<"*****3*****\n"<<endl;
27 
28     // 4 m4按值传递,其它引用
29     cout<<"*****4*****"<<endl;
30     int m4 = 0, n4 = 0;
31     auto f4 = [&, m4](int t)mutable{cout<<"lambada = "<<(m4 = ++n4 + t)<<endl;};
32     f4(10);
33     cout<<"m4 = "<<m4<<endl;
34     cout<<"n4 = "<<n4<<endl;
35     cout<<"*****4*****\n"<<endl;
36 
37     // 5 m5,n5按值传递
38     cout<<"*****5*****"<<endl;
39     int m5 = 0, n5 = 0;
40     auto f5 = [m5, n5](int t)mutable{cout<<"lambada = "<<(m5 = ++n5 + t)<<endl;};
41     f5(10);
42     cout<<"m5 = "<<m5<<endl;
43     cout<<"n5 = "<<n5<<endl;
44     cout<<"*****5*****\n"<<endl;
45 
46     // 6 m6,n6引用传递
47     cout<<"*****6*****"<<endl;
48     int m6 = 0, n6 = 0;
49     auto f6 = [&m6, &n6](int t)mutable{cout<<"lambada = "<<(m6 = ++n6 + t)<<endl;};
50     f6(10);
51     cout<<"m6 = "<<m6<<endl;
52     cout<<"n6 = "<<n6<<endl;
53     cout<<"*****6*****\n"<<endl;
*****1*****
lambda = 11
m1 = 0
n1 = 0
*****1*****

*****2*****
lambada = 11
m2 = 11
n2 = 1
*****2*****

*****3*****
lambada = 11
m3 = 11
n3 = 0
*****3*****

*****4*****
lambada = 11
m4 = 0
n4 = 1
*****4*****

*****5*****
lambada = 11
m5 = 0
n5 = 0
*****5*****

*****6*****
lambada = 11
m6 = 11
n6 = 1
*****6*****

② 操作符重载函数参数;

标识重载的()操作符的参数,没有参数时,这部分可以省略。参数可以通过按值(如:(a,b))和按引用(如:(&a,&b))两种方式进行传递。

③ 可修改标示符;

mutable声明,这部分可以省略。按值传递函数对象参数时,加上mutable修饰符后,可以修改按值传递进来的拷贝(注意是能修改拷贝,而不是值本身)。

④ 错误抛出标示符;

exception声明,这部分也可以省略。exception声明用于指定函数抛出的异常,如抛出整数类型的异常,可以使用throw(int)

⑤ 函数返回值;

->返回值类型,标识函数返回值的类型,当返回值为void,或者函数体中只有一处return的地方(此时编译器可以自动推断出返回值类型)时,这部分可以省略。

⑥ 是函数体;

{},标识函数的实现,这部分不能省略,但函数体可以为空。

 

(摘录自https://blog.csdn.net/alzzw/article/details/99628409

posted @ 2020-09-17 20:51  补码  阅读(150)  评论(0编辑  收藏  举报