lambda表达式

等价于匿名函数对象,又称为“闭包”(closure),更便捷,表达更直接。表达式要素包括:
1:捕获列表
2:参数列表
3:mutable修饰符,表达传值或传引用
4:noexcept
5:返回值类型声明 ->
6:表达式体{...}lambda表达式可接受参数,可返回值,可模板化,也可以通过传值或传引用从闭包范围内访问变量。
编译器将lambda表达式编译为具名函数对象

捕获列表

lambda表达式,从闭包作用域捕获变量而获得状态,分为传值和传引用。
捕获变量登记与函数对象中的示例数据成员。[=] 值捕获所有变量[&] 引用捕获所有变量[&x] 引用捕获x变量[x]  值捕获x[=,&x] 默认值捕获,x变量通过引用捕获[&,x] 默认引用捕获,x通过值捕获[this] 捕获当前对象,可访问所有共有成员,C++20中不允许隐式捕获this[=,x],[&,&x] 错误,重复指定注意:即便默认要值捕获,全局变量总是使用引用捕获使用初始化捕获表达式表达move捕获

示例及分析

#include <iostream>
#include <vector>
using namespace std;class Point{public:double x;double y;void print() const {std::cout << x<< ", "<<y<<endl;;}
};int number=100;  //全局变量可以在lambda修改,跨越所有,捕获类型管理不到
int main()
{Point p1{100,200}; Point p2{100,200};//=表示值捕获,就是将外部变量拷贝进来,声明的时候,只能用auto,因为是匿名对象//如果没有mutable,会报错,不允许修改p1,p2;如果修改捕获对象,就需要mutableauto lambda1 = [=] (int n) mutable    //p1,p2为外部变量,实际调用了拷贝构造函数{p1.x+=n;   //从外部拷贝进来了,此处修改不影响外部p1p1.y+=n;p2.x+=n;p2.y+=n;p1.print();  //print()有个const,如果此时p1,p2没修改(即上面4行不存在),如果print没有const,lambda也需要mutable(编译器认为调用函数也可能更改了)p2.print();number++;  //全局变量直接使用};//Lambda_Value lambda1(p1,p2);lambda1(10);  //外部看不到p1,p2,打印110,210lambda1(10); //多执行一次,会改变lambda对象内部的p1,p2,栈上的lambda对象没有销毁,120,220p1.print();   //不改变外部的p1,p2,所以此处打印是一样的,100,200p2.print();cout<<sizeof(lambda1)<<endl; //没有捕获,就是一个空类,有捕获后,就有32bytecout<<sizeof(Point)<<endl;      //cout<<"lambda1------------"<<endl;auto lambda2 = [&] (int n)   //引用捕获,不用mutable,lambda内部修改会传递到外部{p1.print();p2.print();p1.x+=n;p1.y+=n;p2.x+=n;p2.y+=n;number++;   //全局的执行也有效果};//Lambda_Ref lambda2(p1,p2);lambda2(100);//p1,p2先打印原始值,之后 p1:200,300; p2:200,300p1.print(); //200,300p2.print();p1.x+=5;  //p1.x = 205p1.y+=5; //p1.y = 305p2.x+=5;p2.y+=5;lambda2(100);  //引用捕获,外部更改也会影响引用捕获内部变量,先打印205,305,之后305,405//return lambda2;    //隐蔽错误,因为lambda2是引用捕获,函数返回后,p1,p2销毁了,值捕获就没有问题cout<<number<<endl;    //lambda内部修改此处表现出来了cout<<sizeof(lambda2)<<endl;//只是引用,大小不计算引用参数大小cout<<"lambda2------------"<<endl;auto lambda3 = [=, &p1] ()    //默认值捕获,但p1使用引用捕获{p1.x++;p1.y++; //p1修改外部更改,306,406p2.print(); //值捕获305,405};lambda3();//auto lambda4 = [ &, &p1] () 或者 auto lambda4 = [ =, p1] () 都是重复性错误auto lambda4 = [ &, p1] ()    //默认引用捕获,p1是值捕获{p1.print();  p2.x++;   //引用捕获,p2:306,406p2.y++;};lambda4();//   auto lambda5 = [p2, &number] ()    //失败,number不能auto lambda5 = [p2] () //单独对p2值捕获{p2.print();  //306,406};lambda5();auto lambda6 = [&p1] ()   //单独对p1引用捕获{p1.x++;p1.y++;};lambda6();
}

捕获原理

//引用lambda内存模型,表达式内部p1,p2就是外部的p1,p2
//引用就是同一个地址,本质就是一个别名struct Lambda_Ref{//引用就是一个指针,就是8byte,引用的大小固定了Point& p1;    //生命周期不好管理Point& p2;Lambda_Ref( Point& p1, Point& p2):p1(p1),p2(p2){}void operator()(int n) {p1.x+=n;p1.y+=n;p2.x+=n;p2.y+=n;}};//值捕获生成的代码
struct Lambda_Value{Point p1;Point p2;Lambda_Value(const Point& p1, const Point& p2):p1(p1),p2(p2)  //传值,拷贝{}void operator()(int n) {p1.x+=n;p1.y+=n;p2.x+=n;p2.y+=n;}
};

编译、结果输出

kongcb@tcu-pc:~/testcode/lambda$ g++ lamba_capture.cpp -o lamba_capture
kongcb@tcu-pc:~/testcode/lambda$ ./lamba_capture
110, 210
110, 210
120, 220
120, 220
100, 200
100, 200
32
16
lambda1------------
100, 200
100, 200
200, 300
200, 300
205, 305
205, 305
104
16
lambda2------------
305, 405
306, 406
306, 406

lambda表达式——捕获相关推荐

  1. c++的lambda表达式捕获this_贯穿 C++ 11 与 C++ 17 的 Lambda 到底是个什么?

    本文将详解Lambda函数从定义到学习和使用,涉及一些不为人知的事情,如LIFE-立即调用的函数表达式,Lambda的类型.相信你已经起了兴趣,那就开始阅读吧. 作者 | Vishal Chovati ...

  2. 快用一用 lambda 表达式吧,让你的代码更简洁、更漂亮!

    目录 lambda 表达式 定义 lambda 表达式 捕获子句 按值捕获 按引用捕获 捕获特定的变量 捕获this指针 结合 lambda 使用 STL 算法 lambda 表达式 lambda 表 ...

  3. C++11系列学习之二-----lambda表达式

    C++11添加了一项名为lambda表达式的新功能,通过这项功能可以编写内嵌的匿名函数,而不必编写独立函数和函数对象,使得代码更容易理解. lambda表达式的语法如下所示: [capture_blo ...

  4. C++中的lambda表达式和线程库

    98中的一个例子 如果想要对一个数据集合中的元素进行排序,可以使用std::sort方法 #include <algorithm> #include <functional> ...

  5. Python、C++ lambda 表达式

    Python.C++ lambda 表达式 lambda函数简介 匿名函数lambda:是指一类无需定义标识符(函数名)的函数或子程序.所谓匿名函数,通俗地说就是没有名字的函数,lambda函数没有名 ...

  6. C++11:lambda表达式

    文章目录 1. 概念 2. 语法 3. 示例 示例1 示例2 示例3 示例4 4. 捕捉方式 基本方式 隐式和混合 补充 5. 传递lambda表达式 示例 6. 原理 7. 内联属性 1. 概念 l ...

  7. Java - Lambda 表达式

    一.背景 Lambda表达式是Java SE 8中一个重要的新特性.lambda表达式允许你通过表达式来代替功能接口. lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主 ...

  8. VC10和C++ 0x (1) - lambda表达式

    来源: <http://www.cnblogs.com/brucejia/archive/2009/09/05/1560675.html> [本文大部分内容译自Visual C++ Tea ...

  9. C++Lambda表达式

    文章目录 1. Lambda表达式 1.1. 声明Lambda表达式 1.2. 捕获外部变量 1.2.1. 值捕获 1.2.2. 引用捕获 1.2.3. 隐式捕获 1.2.4. 混合方式 1.3. L ...

最新文章

  1. java分布式锁终极解决方案之 redisson
  2. nodejs的安装for mac
  3. Discuz常见大问题-如何使用云采集插件
  4. PowerDesigner使用教程【转】
  5. 图谱实战 | 安全领域知识图谱建设与典型应用场景总结
  6. LeetCode 665 非递减数列
  7. python交互模式下tab键自动补全
  8. fft 相位谱_基于级联FFT的广义互相关算法在声源定位中的应用
  9. IDC带宽测试几款软件(Multiping pingPlotter TracertGUI )
  10. typora 语法教程
  11. 泰拉瑞亚Terraria for Mac(动作冒险游戏)
  12. 计算机关闭窗口可以使用alt,电脑关闭窗口快捷键
  13. Android FFMpeg 播放器
  14. APP推广:app推广的渠道有哪些既简单又有效的?
  15. 电脑无缘无故黑屏,无法调节亮度。
  16. 【转】宁做创业狼,不做打工狗(ZT)
  17. 74HC595级联电路编程篇(四)
  18. 物联网开发笔记(9)- 使用Wokwi仿真MicroPython on ESP32开发板实现温度和湿度检测并使用屏幕显示
  19. AB实验平台在贝壳找房的设计与实践
  20. 读书笔记-精准努力-励志本身就已经让你爽了以为自己真这样做了

热门文章

  1. P1264 复制书稿
  2. 孪生素数【函数实现】
  3. 我做数画ai绘画教程日赚过千,良心分享给想兼职赚钱的人
  4. fluent bit 安装及配置
  5. 10倍杠杆炒股是什么意思
  6. 2022Q3手机配件增长榜:手机壳、数据线等供求不断增加
  7. 微信支付服务商模式签名错误小坑
  8. Neighbourhood Consensus Networks(NIPS 2018)特征点检测与匹配论文笔记
  9. 基于SSH框架的二手物品交易网(Struts)
  10. 淘宝上还有卖这种服务的