C++11之lambda表达式理解与使用
创始人
2024-03-08 04:44:15
0

目录

 0.痛点需求:

1.lambda表达式背景

2、C++11 lambda语法

3、C++11 lambda表达式捕获列表

4、lambda表达式测试例子(帮助理解)

5、总结

6、lambda表达式修改外界捕获的值


 0.痛点需求:

  在阅览AOSP源码时,特别高版本AOSP源码中的HIDL代码中,经常看到C++使用lambda表达式,函数并且特别长,总是搞得一头雾水,让许多C程序员望而却步。磨刀不误砍柴工,通过几个对lambda表示的语法、demo,来理解下lambda表达式的用法。

1.lambda表达式背景

在C++11标准中引入了lambda表达式,一般用于定义匿名函数,使得代码更加灵活简洁。

  lambda表达式与普通函数类似,也有参数列表、返回值类型和函数体,只是它的定义方式更简洁,并且可以在函数内部定义。

  准确的来说,现在的所谓高级语言(java、python、erlang、C++等)的lambda表达式,都是从lisp及其方言发展过来的,在20十世纪五六十年代,lisp作为人工智能语言,lambda表达式一直它的专属,所以说lisp是lambda表示的始祖也不过为过。

 便于理解:将lambda表达式看成一个函数即可。

2、C++11 lambda语法

1.C++11允许省略lambda表达式的返回值类型定义:auto f = [](int a){ return a + 1; };注意:
编译器可以根据return 语句自动推导出返回值类型。2.初始化列表时,不能用于返回值的自动推导:auto x1 = [](int i){ return i; };  // OK: return type is int
auto x2 = [](){ return { 1, 2 }; };  // failed: 无法推导出返回值类型此时需要显式给出具体的返回值类型。3.lambda表达式在没有参数列表时,参数列表是可以省略的:auto f1 = [](){ return 1; }; //OK
auto f2 = []{ return 1; };  // OK: 省略空参数表

3、C++11 lambda表达式捕获列表

lambda表达式还可以通过捕获列表捕获一定范围内的变量:
<1>.[]:不捕获任何变量。<2>.[&]:捕获外部作用域中所有变量,并作为引用在函数体中使用(按引用捕获)。<3>.[=]:捕获外部作用域中所有变量,并作为副本在函数体中使用(按值捕获)。<4>.[=,&foo]:按值捕获外部作用域中所有变量,并按引用捕获 foo 变量。<5>.[bar]:按值捕获bar变量,同时不捕获其他变量。<6>.[this]:捕获当前类中的this指针,就可以在lambda表达式访问成员函数和成员变量。
注意:如果使用了&或者=的话,就可以默认使用this指针访问成员函数。

4、lambda表达式测试例子(帮助理解)

#include 
using namespace std;class A {
public:int count = 10;int tmp = 99;void func(int x, int y){// error,没有捕获外部变量,所以访问外界的count和tmp变量,会报错不允许访问.//auto x1 = []{ return count; };// OK,按值捕获所有外部变量:count和tmpauto x2 = [=]{printf("x2: count = %d\n",tmp);printf("x2: count = %d\n",this->count);return count + x + y;};printf("x2 = %d\n",x2());// OK,按引用捕获所有外部变量:count和tmpauto x3 = [&]{printf("x3: count = %d\n",tmp);printf("x3: count = %d\n",this->count);return count + x + y;};printf("x3 = %d\n",x3());// OK,捕获this指针:可以访问count和tmpauto x4 = [this]{printf("x4: this->tmp = %d\n",this->tmp);printf("x4: this->count = %d\n",this->count);return count;};printf("x4 = %d\n",x4());// error,虽然捕获了this指针,但是没有捕获x,y,但是却使用x,y,所以会报错.//auto x5 = [this]{ return count + x + y; };// OK,捕获this指针、x、yauto x6 = [this, x, y]{printf("x4: this->tmp = %d\n",this->tmp);printf("x4: this->count = %d\n",this->count);return count + x + y;};printf("x6 = %d\n",x6());// OK,捕获this指针,并修改成员的值auto x7 = [this]{ return count++; };}
};int main(){//1.最简单的lambda表达式:以中括号"[]"开头,没有函数名字的定义,像是一个匿名函数.auto f = [](int a)->int { return a + 1; };cout << " f(1) = "<< f(1) << endl;//2.//<1>.测试1[]{cout << "Lambda空" << endl;}();//<2>.测试2auto FuncAdd = [](int a, int b)->int {return a + b; };int xx = FuncAdd(2, 3);cout << "xx = " << xx << endl;//<3>.测试3:: []外部参数:值传递auto FuncMultiPly = [xx](int a)->int {cout << "xx = " << xx << endl;cout << "a + xx = " << a + xx << endl;return a + xx;};FuncMultiPly(23);//<4>.测试4: 隐式捕获变量bint b = 23;auto FuncHide = [&]{cout <<"b = "<<  b << endl;};FuncHide();//3.lambda表达式访问外部变量A* aa = new A();aa->func(1,2);}

5、总结

<1>.从上demo看到,lambda表达式捕获列表,lambda 表达式能够访问的外部变量
<2>. 默认状态下,lambda表达式无法修改通过复制方式(即传值方式)捕获的外部变量。

       如果希望修改这些变量,需要使用引用方式进行捕获。

如下例子传值和传引用demo:

6、lambda表达式修改外界捕获的值

#include 
using namespace std;int main(){int id1 = 10;int id2 = 50;//1.传值  auto f1 = [id1] () mutable {cout << "id1: " << id1 << endl;++id1;};f1();  cout << id1 << endl;//2.传引用auto f2 = [&id2] () mutable {cout << "id2: " << id2 << endl;++id2;};f2();  cout << id2 << endl;//3.带参数的lambda表达式int round = 2;auto f3 = [&](int tmp){cout << "tmp = " << tmp << endl;return tmp + round;} ;auto nn = f3(2);cout << "nn = " << nn << endl;return 0;
}

相关内容

热门资讯

最新!靖国神社被起诉 据央视新闻,当地时间23日,二战时期被日军强制征兵的部分韩籍遇难者遗属向首尔中央地方法院提起诉讼,要...
靖国神社,被起诉! 当地时间23日,二战时期被日军强制征兵的部分韩籍遇难者遗属向首尔中央地方法院提起诉讼,要求日本靖国神...
国台办:为“台独”分裂势力为虎... 中新社北京12月24日电 (陈建新 李百加)国务院台办发言人彭庆恩24日在北京表示,凡危害国家主权、...
怀宁县清河乡“一站式”调解架起... 诉求“只进一扇门”,调处“最多跑一地”。在怀宁县清河乡,这不仅仅是一句口号,更是当地群众化解矛盾纠纷...
钧达股份:充分利用海南相关优惠... 证券之星消息,钧达股份(002865)12月23日在投资者关系平台上答复投资者关心的问题。 投资者提...
信用修复制度助力企业重塑信用 信用修复作为社会信用体系建设的关键环节,对于帮助信用主体纠正错误、重塑信用、重返市场具有不可替代的作...
《秦皇岛市餐厨废弃物管理条例》... 12月23日,记者从市政府新闻办召开的《秦皇岛市餐厨废弃物管理条例》(以下简称《条例》)颁布实施新闻...
最高法等三部门联合发布婚姻家庭... 家和万事兴,家齐国安宁。为深入学习贯彻党的二十大和二十届历次全会精神,贯彻落实习近平总书记关于注重家...
追债超9000万元遇阻!被告破... 12月23日,瀚川智能(688022)发布公告,近日公司收到江西省吉安市中级人民法院对公司出具的《民...