C++11新增特性2

news/2024/12/3 4:44:27/

一.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.ppmy.cn/news/1551910.html

相关文章

跨平台应用开发框架(3)-----Qt(样式篇)

目录 1.QSS 1.基本语法 2.QSS设置方式 1.指定控件样式设置 2.全局样式设置 1.样式的层叠特性 2.样式的优先级 3.从文件加载样式表 4.使用Qt Designer编辑样式 3.选择器 1.类型选择器 2.id选择器 3.并集选择器 4.子控件选择器 5.伪类选择器 4.样式属性 1.盒模型 …

分布式锁的实现原理

作者&#xff1a;来自 vivo 互联网服务器团队- Xu Yaoming 介绍分布式锁的实现原理。 一、分布式锁概述 分布式锁&#xff0c;顾名思义&#xff0c;就是在分布式环境下使用的锁。众所周知&#xff0c;在并发编程中&#xff0c;我们经常需要借助并发控制工具&#xff0c;如 mu…

opengl 三角形

最后效果&#xff1a; OpenGL version: 4.1 Metal 不知道为啥必须使用VAO 才行。 #include <glad/glad.h> #include <GLFW/glfw3.h>#include <iostream> #include <vector>void framebuffer_size_callback(GLFWwindow *window, int width, int heigh…

Unity类银河战士恶魔城学习总结(P150 End Screen结束重启按钮)

【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili 教程源地址&#xff1a;https://www.udemy.com/course/2d-rpg-alexdev/ 本章节实现了死亡后重新启动游戏&#xff0c;并且加入了游戏管理器 加入了重新开始游戏的按钮 GameManager.cs using System.Collection…

vue3中 axios 发送请求 刷新token 封装axios

service.js 页面 import axios from axios // 创建axios实例 const instance axios.create({baseURL: http://gcm-test.jhzhkj.cn:8600/h5card/,timeout: 5000, // 请求超时时间headers: {get: {Content-Type: application/x-www-form-urlencoded},post: {Content-Type: appl…

根据后台数据结构,构建搜索目录树

效果图&#xff1a; 数据源 const data [{"categoryidf": "761525000288210944","categoryids": "766314364226637824","menunamef": "经济运行","menunames": "经济运行总览","tempn…

[Go] slice切片详解

切片详解 切片的实现 Go 中的切片本质上是一个结构体&#xff0c;包含以下三个部分&#xff1a; 指向底层数组的指针&#xff08;array&#xff09;&#xff1a;切片指向一个底层数组&#xff0c;数组中存储着切片的数据。切片的长度&#xff08;len&#xff09;&#xff1a…

通信原理实验:PCM编译码

目录 一、实验目的和要求 二、实验内容和原理 实验器材 实验原理 实验原理框图 实验框图说明 三、实验步骤 实验项目二 PCM 编码规则验证 四、实验记录与处理(数据、图表、计算等) 五、实验结果及分析 一、实验目的和要求 掌握脉冲编码调制与解调的原理。掌握脉冲编…