当前位置: 首页 > article >正文

C++11新增特性2

一.lambda

1.本质:lambda对象是⼀个匿名函数对象,它可以定义在函数内部。

注:lambda表达式语法使⽤层⽽⾔没有类型,所以我们⼀般是⽤auto或者模板参数定义的对象去接收lambda对象。

2.表达式:[capture-list] (parameters)-> return type { function boby }

捕捉列表:

<1>该列表出现在lambda函数的开始位置,编译器根据[]来判断接下来的代码是否为lambda函数

<2>捕捉列表能够捕捉上下⽂中的变量供lambda函数使⽤,捕捉列表可以传值捕捉和传引⽤捕捉

<3>捕捉列表哪怕为空也不能省略。

参数列表:

<1>与普通函数的参数列表功能类似

<2>如果不需要参数传递,则可以连同()⼀起省略

返回值:

<1>⽤追踪的返回类型形式来声明函数的返回值类型

<2>没有返回值时,此部分可省略;⼀般返回值类型明确情况下,也可省略,由编译器对返回类型进⾏推导。

函数体:

<1>函数体的实现跟普通函数完全类似,在该函数体内,除了可以使⽤其参数外,还可以使⽤所有捕获到的变量

<2>函数体为空也不能省略。

3.捕捉列表:lambda的捕捉列表本质是生成的仿函数类的成员变量。lambda表达式中默认只能⽤lambda函数体和参数中的变量,如果想⽤外层作⽤域中的变量就需要进⾏捕捉,捕捉方式有三种:

<1>捕捉列表中显示的传值捕捉和传引⽤捕捉,捕捉的多个变量⽤逗号分割。例如:[x,y,&z]表示x和y值捕捉,z引⽤捕捉。

注1:传值捕捉时,该值相当于被const修饰,不可以在函数体内被更改,此时可将mutable加在参数列表的后⾯取消其常量性,即使⽤该修饰符后,传值捕捉的对象就可以被修改了,但是修改还是形参对象,不会影响实参。注意使⽤该修饰符后,参数列表不可省略(即使参数为空)。

注2:传引用捕捉时,可以在函数体内修改该值

<2>在捕捉列表中隐式捕捉,我们在捕捉列表写⼀个=表示隐式值捕捉,在捕捉列表写⼀个&表示隐式引⽤捕捉,这样lambda表达式中⽤了哪些变量,编译器就会⾃动捕捉那些变量。

<3>在捕捉列表中混合使⽤隐式捕捉和显示捕捉。例如:[=,&x]表⽰其他变量隐式值捕捉,x引⽤捕捉;[&,x,y]表示其他变量引⽤捕捉,x和y值捕捉。

注:当使⽤混合捕捉时,第⼀个元素必须是&或=,并且&混合捕捉时,后⾯的捕捉变量必须是值捕捉,同理=混合捕捉时,后⾯的捕捉变量必须是引⽤捕捉。

4.原理:lambda底层是仿函数对象。即写了⼀个lambda以后,编译器会⽣成⼀个对应的仿函数的类。仿函数的类名是编译按⼀定规则⽣成的,保证不同的lambda⽣成的类名不同,lambda参数/返回类型/函数体就是仿函数operator()的参数/返回类型/函数体,lambda的捕捉列表本质是⽣成的仿函数类的成员变量,即捕捉列表的变量都是lambda类构造函数的实参,若为隐式捕捉,编译器要看使⽤哪些就传哪些对象。

5.lambda表达式如果在函数局部域中,它可以捕捉lambda位置之前定义的变量,但是不能捕捉静态局部变量和全局变量,静态局部变量和全局变量也不需要捕捉,lambda表达式中可以直接⽤。

注:lambda表达式如果定义在全局位置,捕捉列表必须为空。

6.使用场景:使⽤lambda定义可调⽤对象;线程中定义线程的执⾏函数逻辑;智能指针中定
制删除器……

二.新的类功能

1.默认的移动构造和移动赋值

回顾:原来C++类中,有6个默认成员函数:构造函数;析构函数;拷⻉构造函数;拷⻉赋值重载;取地址重载;const取地址重载,最后重要的是前4个

<1>C++11新增了两个默认成员函数,移动构造函数和移动赋值运算符重载。

<2>移动构造:如果没有自定义实现移动构造函数,且没有实现析构函数、拷⻉构造、拷⻉赋值重载中的任意⼀个,那么编译器会⾃动⽣成⼀个默认移动构造。

默认⽣成的移动构造函数对于内置类型:逐成员按字节拷⻉

默认⽣成的移动构造函数对于自定义类型:如果这个成员需要实现移动构造,则调⽤移动构造;若是不需要实现移动构造,调⽤拷⻉构造。

<3>移动赋值:如果没有自定义实现移动赋值重载函数,且没有实现析构函数、拷⻉构造、拷⻉赋值重载中的任意⼀个,那么编译器会⾃动⽣成⼀个默认移动赋值重载函数。

默认⽣成的移动赋值重载函数对于内置类型:逐成员按字节拷⻉

默认⽣成的移动赋值重载函数对于自定义类型:如果这个成员需要实现移动赋值,则调⽤移动赋值;若是不需要实现移动赋值,调⽤拷贝赋值。

<4>如果自定义了移动构造或者移动赋值,那么编译器不会⾃动提供拷⻉构造和拷⻉赋值。

2.成员变量声明时给缺省值:成员变量声明时给缺省值是给初始化列表使⽤的,如果没有显示在初始化列表初始化,那么初始化列表就⽤这个缺省值初始化

3.default和delete

控制要使用的默认函数:default关键字显示指定移动构造⽣成。

限制默认函数的生成:

(1)在C++98中,将该函数设置成private,并且只声明不调用

(2)在C++11中,在该函数声明后加上=delete即可,该语法指示编译器不⽣成对应函数的默认版本,故称 =delete 修饰的函数为删除函数。

4.final和override

final:用于修饰类,被final修饰的类不可以被继承

override:用于修饰派生类,被override修饰的派生类不可以被重写

5.STL中的变化

C++11在STL中新增的内容中,新容器:unordered_map,unordered_set和新接口:emplacement对于提高效率有很大帮助

三.包装器

注:function,bind被定义<functional>头⽂件

1.function

<1>本质:std::function是⼀个类模板,也是⼀个包装器。

<2>作用:std::function的实例对象可以包装存储其他的可以调⽤对象,包括函数指针、仿函数、lambda、bind表达式等,存储的可调⽤对象被称为std::function的⽬标。

注:若std::function不含⽬标,则称它为空。调⽤空std::function的⽬标导致抛出std::bad_function_call异常。

<3>function原型:

template <class T>
class function;    

template <class Ret, class... Args>
class function<Ret(Args...)>;

<4>优势:统⼀不同对象的类型,对它们都可以进⾏包装,这样在很多地⽅就⽅便声明可调⽤对象的类型

2.bind

<1>bind是⼀个函数模板,它也是⼀个可调⽤对象的包装器,可以把他看做⼀个函数适配器,对接收的fn可调⽤对象进⾏处理后返回⼀个可调⽤对象。

<2>作用:bind可以⽤来调整参数个数和参数顺序。

注:bind调整参数个数的实际用途不大,但是改变参数顺序的实际意义很大

<3>格式:auto newCallable = bind(callable,arg_list);

解释:当调⽤newCallable时,newCallable会调⽤callable,并传给它arg_list中的参数。

newCallable本⾝是⼀个可调⽤对象;

arg_list是⼀个逗号分隔的参数列表,对应给定的callable的参数。arg_list中的参数可能包含形如_n的名字,其中n是⼀个整数,这些参数是占位符,表⽰newCallable的参数,它们占据了传递给newCallable的参数的位置。数值n表⽰⽣成的可调⽤对象中参数的位置,例如:_1为newCallable的第⼀个参数,_2为第⼆个参数,以此类推。_1/_2/_3....这些占位符放到placeholders的⼀个命名空间中。

注:通过改变arg_list中占位符的位置,可以实现改变参数的顺序;也可以通过在某位置指定具体值,利用占位符确定传入参数的位置,从而实现某个变量的绑定


http://www.kler.cn/a/418901.html

相关文章:

  • 项目代码第1讲:各个文件夹是什么意思?按照官方文档教程创建项目,各个文件夹的理解、框架自主生成的Controller(Restful风格)
  • 【绘图】数据可视化(python)
  • YOLO系列论文综述(从YOLOv1到YOLOv11)【第11篇:YOLO变体——YOLO+Transformers、DAMO、PP、NAS】
  • 华为小米苹果三星移动设备访问windows共享文件夹windows11
  • 深度学习基础02_损失函数BP算法(上)
  • git的学习笔记
  • vue3typescript,shims-vue.d.ts中declare module的vue声明
  • C-操作符
  • Linux虚拟机安装nginx踩坑记录
  • 《UDS协议从入门到精通(UDS速查手册)》(完结撒花版)
  • Java之链表1
  • vue3+elPlus 选择框select 下拉数据过千条,页面卡顿,分页解决
  • Java中 HttpURLConnection 和 HttpClient 详解(初学者友好)
  • 【从零开始的LeetCode-算法】3208. 交替组 II
  • 【Git教程 之 版本控制】
  • 深入探讨SQL优化原理 - 增量查询和索引加速
  • JavaScript 高级教程:异步编程、面向对象与性能优化
  • EC2还原快照
  • 探索3D世界:使用 lib3ds 读取和解析 3DS 文件
  • CentOS使用chrony服务进行时间同步源设置脚本
  • CSS3网站
  • 欧拉函数——acwing
  • 挑战用React封装100个组件【005】
  • 【linux】(23)对象存储服务-MinIo
  • Linux 僵尸进程和孤儿进程, 进程优先级
  • Android 12.0新增自定义HIDL问题记录