131.lambda表达式小结

C++ 11中的Lambda表达式用于定义并创建匿名的函数对象,以简化编程工作。Lambda的语法形式如下:
[函数对象参数](操作符重载函数参数) mutable或exception声明->返回值类型{ 函数体 }

可以看到,Lambda主要分为五个部分:
[函数对象参数]、(操作符重载函数参数)、mutable或exception声明、->返回值类型、{ 函数体 }。下面分别进行介绍。
一、[函数对象参数],标识一个Lambda的开始,这部分必须存在,不能省略。函数对象参数是传递给编译器自动生成的函数对象类的构造函数的。
函数对象参数只能使用那些到定义Lambda为止时Lambda所在作用范围内可见的局部变量(包括Lambda所在类的this)。函数对象参数有以下形式:
1、空。没有使用任何函数对象参数。
2、 = 。函数体内可以使用Lambda所在作用范围内所有可见的局部变量(包括Lambda所在类的this),并且是值传递方式(相当于编译器自动为我们按值传递了所有局部变量)。
3、&。函数体内可以使用Lambda所在作用范围内所有可见的局部变量(包括Lambda所在类的this),并且是引用传递方式(相当于编译器自动为我们按引用传递了所有局部变量)。
4、this。函数体内可以使用Lambda所在类中的成员变量。
5、a。将a按值进行传递。按值进行传递时,函数体内不能修改传递进来的a的拷贝,因为默认情况下函数是const的。要修改传递进来的a的拷贝,可以添加mutable修饰符。
6、&a。将a按引用进行传递。
7、a, &b。将a按值进行传递,b按引用进行传递。
8、 = ,&a, &b。除a和b按引用进行传递外,其他参数都按值进行传递。
9、&, a, b。除a和b按值进行传递外,其他参数都按引用进行传递。
二、(操作符重载函数参数),标识重载的()操作符的参数,没有参数时,这部分可以省略。参数可以通过按值(如:(a, b))和按引用(如:(&a, &b))两种方式进行传递。
三、mutable或exception声明,这部分可以省略。按值传递函数对象参数时,加上mutable修饰符后,可以修改按值传递进来的拷贝(注意是能修改拷贝,而不是值本身)。
exception声明用于指定函数抛出的异常,如抛出整数类型的异常,可以使用throw(int)。
四、->返回值类型,标识函数返回值的类型,当返回值为void,或者函数体中只有一处return的地方(此时编译器可以自动推断出返回值类型)时,这部分可以省略。
五、{ 函数体 },标识函数的实现,这部分不能省略,但函数体可以为空。

代码示例

  1 #include <functional>
  2 #include <iostream>
  3 #include<vector>
  4 #include<algorithm>
  5 using namespace std;
  6 
  7 void main1()
  8 {
  9 
 10     auto fun1 = [](){cout << "hello china"; };
 11     fun1();
 12 
 13     auto fun2 = [](int a, int b){return a + b; };
 14     cout << fun2(10, 9) << endl;
 15 
 16 
 17     std::cin.get();
 18 }
 19 
 20 void main2()
 21 {
 22     vector<int>  myv;
 23     myv.push_back(1);
 24     myv.push_back(2);
 25     myv.push_back(11);
 26     auto fun1 = [](int v){  cout << v << endl; };
 27     for_each(myv.begin(), myv.end(), fun1);
 28     
 29     std::cin.get();
 30 }
 31 
 32 void main3()
 33 {
 34     vector<int>  myv;
 35     myv.push_back(1);
 36     myv.push_back(2);
 37     myv.push_back(11);
 38 
 39     int a = 10;
 40     // =知道a的存在,可以引用,只能读,不可以写,引用当前块语句内部的局部变量
 41     auto fun1 = [=](int v){ v += a;  cout << v << endl;  };
 42 
 43     for_each(myv.begin(), myv.end(), fun1);
 44     cout << a << endl;
 45     std::cin.get();
 46 
 47 
 48 
 49 }
 50 
 51 void main4()
 52 {
 53     vector<int>  myv;
 54     myv.push_back(1);
 55     myv.push_back(2);
 56     myv.push_back(11);
 57 
 58     int a = 10;
 59     //引用变量a,
 60     auto fun1 = [&a](int v){a = 3; v += a;  cout << v << endl;  };
 61 
 62     for_each(myv.begin(), myv.end(), fun1);
 63     cout << a << endl;
 64     std::cin.get();
 65 
 66 
 67 
 68 }
 69 
 70 void main5()
 71 {
 72 
 73      [](){cout << "hello china"; };//是一个函数指针
 74      [](){cout << "hello china"; }();//调用函数
 75 
 76      cin.get();
 77 }
 78 
 79 class test
 80 {
 81 public:
 82     vector<int>  myv;
 83     int num;
 84 public:
 85     test()
 86     {
 87         num = 12;
 88         myv.push_back(10);
 89         myv.push_back(11);
 90     }
 91     void add()
 92     {
 93         
 94         //[]引用this
 95         int  x = 3;
 96         //auto fun1 = [this,x](int v){ cout << v+x+this->num << endl; };
 97         //=按照副本引用this,还有当前块语句局部变量,不可以赋值,但是可以读取
 98         //&按照引用的方式操作局部变量,this,可以赋值,可以读取
 99         //副本引用a,[=]   [a]
100         //引用 a [&]  [&a]
101 
102         auto fun1 = [&](int v){ cout << v + x + this->num << endl; x = 3; };
103         for_each(this->myv.begin(), this->myv.end(), fun1);
104 
105     }
106 };
107 
108 
109 void mainS ()
110 {
111 
112     //double是返回值类型
113     auto fun1 = []()->double{cout << "hello china"; return 1; };
114     fun1();
115 
116     auto fun2 = [](int a,double b)->decltype(a/b){cout << "hello china"; return a/b; };
117     fun2(1,2.3);
118 
119     cin.get();
120 }
121 
122 
123 void main()
124 {
125 
126     int a = 10;
127     auto fun1 = [a](int v)mutable->double{ v += a;  cout << v << endl; a = 3; return 3; };
128     cout << a << endl;
129 
130     std::cin.get();
131 
132 }
原文地址:https://www.cnblogs.com/xiaochi/p/8652470.html