C/C++ ③ —— C++11新特性

1. 类型推导

1.1 auto

  • auto可以让编译器在编译期就推导出变量的类型
    • auto的使⽤必须⻢上初始化,否则⽆法推导出类型
    • auto在⼀⾏定义多个变量时,各个变量的推导不能产⽣⼆义性,否则编译失败
    • auto不能⽤作函数参数
    • 在类中auto不能⽤作⾮静态成员变量
    • auto不能定义数组,可以定义指针
    • auto⽆法推导出模板参数
    • 在不声明为引⽤或指针时,auto会忽略等号右边的引⽤类型和const(常量)、volatile(易变性)限定
    • 在声明为引⽤或者指针时,auto会保留等号右边的引⽤和cv属性

1.2 decltype

  • ⽤于推导表达式类型,这⾥只⽤于编译器分析表达式的类型,表达式实际不会进⾏运算
  • decltype不会像auto⼀样忽略引⽤和cv属性,decltype会保留表达式的引⽤和cv属性
  • 对于decltype(exp),若exp是表达式,decltype(exp)和exp类型相同;若exp是函数调⽤,decltype(exp)和函数返回值类型相同;若exp是左值,decltype(exp)是exp类型的左值引⽤。
  • auto和decltype配合使用:
template<typename T, typename U>
auto add(T t, U u)->decltype(t + u){
	return t + u;
}

2. 范围for循环

  • 基于范围的迭代写法,for(变量:对象)表达式:
string str ("some thing");
for(char c : str) cout << c << endl;
  • 对vector中的元素进⾏遍历:
vector<int> arr(5, 100);
for(vector<int>::iterator i = arr.begin(); i != arr.end(); ++i) cout << *i << endl;
for(auto &i : arr) cout << i << endl;

3. 右值引用

3.1 左值和右值

  • 左值:可以放在等号左边,可以取地址并有名字
  • 右值:不可以放在等号左边,不能取地址,没有名字
    • 其定义形式为:Type &&var;其中 Type 表示变量的类型,var 表示变量名。
  • ++i、–i是左值,i++、i–是右值

3.2 左值引用和右值引用

  • 左值引用:
    • 左值引⽤就是对左值进⾏引⽤的类型,是对象的⼀个别名
    • 并不拥有所绑定对象的堆存,所以必须⽴即初始化。 对于左值引⽤,等号右边的值必须可以取地址,如果不能取地址,则会编译失败,或者可以使⽤const引⽤形式
  • 右值引用:
    • 右值引用所引用的对象是一个右值,右值对象是指其生命周期即将结束的对象,例如一次函数调用的返回值、临时变量等。
    • 表达式等号右边的值需要是右值,可以使⽤std::move函数强制把左值转换为右值

3.3 右值引用的使用场景

  • 以字符串类为例,假设有一个字符串对象 A,我们要把它赋值给另外一个字符串对象 B
string A = "HELLO";
string B = A;
  • 这样做的结果是,我们创建了两个相同内容但是不同地址的字符串对象,其中一个占用了额外的内存,存在性能问题。
  • 为了解决这个问题,C++11 移动语义提供了将对象 A 移动到 B 中的操作:
    • 当我们需要把一个对象赋值给另一个对象时,编译器会调用其复制构造函数或者赋值构造函数来创建一个新对象。但是,在某些情况下,复制操作会非常耗时;如果复制操作是不必要的,此时,使用移动构造函数,它不需要复制整个对象,而只是需要将原对象中的指针等资源转移到目标对象中即可,这样可以提高复制性能。
string A = "HELLO";
string B = std::move(A);
  • 上述代码就可以把对象 A 移动到 B 中,并不需要创建新的对象和分配内存。
  • 需要注意的是,只能对一个右值引用或者一个将要销毁的对象调用 std::move() 函数,否则会导致潜在的内存问题和错误。此外,在使用右值引用时,需要注意数据的生命周期问题,不要在使用后再次使用已经被移动的对象。

3.4 forward 完美转发

  • forward 完美转发实现了参数在传递过程中保持其值属性的功能,即若是左值,则传递之后仍然是左值,若是右值,则传递之后仍然是右值。
  • &&既可以对左值引用,亦可以对右值引用,但它后面的val值本身是个左值;&只能左值引用
template <class T>
void Print(T &t){ cout << "L" << t << endl; }
template <class T>
void Print(T &&t){ cout << "R" << t << endl; }

template <class T>
void func(T &&t){
	Print(t);    
	Print(move(t));    
	Print(forward<T>(t));
}

int main(){
	cout << "-- func(1) --" << endl;    
	func(1);  
	
	cout << "-- func(x) --" << endl;  
	int x = 10;    
	int y = 20;    
	func(x);  // x本身是左值    
	
	cout << "-- func(forward<int>(y)) --" << endl;    
	func(forward<int>(y)); //T为int,以右值方式转发y    
	
	cout << "-- func(forward<int&>(y)) --" << endl;    
	func(forward<int&>(y));    
	
	cout << "-- func(forward<int&&>(y)) --" << endl;    
	func(forward<int&&>(y));    
	
	return 0;
}

运行结果:在这里插入图片描述

3.5 emplace_back 减少内存拷贝和移动

  • emplace_back能就地通过参数构造对象,不需要拷贝或者移动内存,相比 push_back能更好地避免内存的拷贝与移动,使容器插入元素的性能得到进一步提升。在大多数情况下应该优先使用emplace_back来代替push_back。

4. lambda 匿名函数

  • 表示⼀个可调⽤的代码单元,没有命名的内联函数,不需要函数名因为我们直接(⼀次性的)⽤它,不需要其他地⽅调⽤它
  • 一般情况下,编译器可以自动推断出lambda表达式的返回类型,所以我们可以不指定返回类型。但是如果函数体内有多个return语句时,编译器无法自动推断出返回类型,此时必须指定返回类型。
  • 语法:[ 捕获列表 ] (参数列表) -> 返回类型 { 函数体 }
int main(){
	auto Add = [](int a, int b)->{ return a+b; };
	cout << Add(1, 2) << endl;
	return 0;
}

值捕获

void func() {     // c=10 d=20 add(1,2)=23
	int c = 10;
	int d = 20;
	auto add = [c, d](int a, int b) {
		cout << "c=" << c << endl;
		cout << "d=" << d << endl;
		return d+a+b;
	};
	d = 50;
	cout << "add(1, 2)=" << add(1, 2) << endl;
}

引用捕获

void func() {    // c=1 d=50 add(1,2)=53
	int c = 10;
	int d = 20;
	auto add = [&c, &d](int a, int b) {
		c = a;
		cout << "c=" << c << endl;
		cout << "d=" << d << endl;
		return d+a+b;
	};
	d = 50;
	cout << "add(1, 2)=" << add(1, 2) << endl;
}

隐式捕获、空捕获

void func() {
	int c = 10;
	int d = 20;
	// 如果[&]代表引用捕获,[=]代表值捕获,如果[]为空捕获表示Lambda不能使用所在函数中的变量
	auto add = [&](int a, int b) {  
		c = a; 
		cout << "c=" << c << endl;
		cout << "d=" << d << endl;
		return d+a+b;
	};
	d = 50;
	cout << "add(1, 2)=" << add(1, 2) << endl;
}

表达式捕获

// c++14之后支持捕获右值,允许捕获的成员用任意的表达式进行初始化,被声明的捕获变量类型会根据 表达式进行判断,判断方式与使用 auto 本质上是相同的
void func4() {
	auto p = make_unqiue<int>(1);
	auto add = [v1=1, v2=move(p)](int x, int y)->int{ return x+y+v1+(*v2); };
	cout << "add(1, 2)=" << add(1, 2) << endl;
}

泛型捕获

void func() {
	auto add = [](auto x, auto y){ return x+y; };
	cout << "add(1, 2)=" << add(1, 2) << endl;
	cout << "add(1.1, 2.2)=" << add(1.1, 2.2) << endl;
}

可变

// 采用值捕获的方式,lambda不能修改其值,如果想要修改,使用mutable修饰;或者采用引用捕获的方式
void func() {
	int v = 5;
	auto ff = [v]() mutable { return ++v; };
	v = 0;
	auto j = ff(); // ff捕获的是值,即为5,因此j为6

	int m = 5;
	auto gg = [&m] {return ++m; };
	m = 0;
	auto n = gg(); // gg捕获的是引用,即为0,因此n为1
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/498162.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MYSQL数字函数:不可不知的数据处理利器

&#x1f308; 个人主页&#xff1a;danci_ &#x1f525; 系列专栏&#xff1a;《设计模式》 &#x1f4aa;&#x1f3fb; 制定明确可量化的目标&#xff0c;坚持默默的做事。 &#x1f680; 转载自&#xff1a;MYSQL数字函数&#xff1a;不可不知的数据处理利器 ✨​​​​​…

快速上手Spring Cloud 十五:与人工智能的智慧交融

快速上手Spring Cloud 一&#xff1a;Spring Cloud 简介 快速上手Spring Cloud 二&#xff1a;核心组件解析 快速上手Spring Cloud 三&#xff1a;API网关深入探索与实战应用 快速上手Spring Cloud 四&#xff1a;微服务治理与安全 快速上手Spring Cloud 五&#xff1a;Spring …

使用pytorch构建一个无监督的深度卷积GAN网络模型

本文为此系列的第二篇DCGAN&#xff0c;上一篇为初级的GAN。普通GAN有训练不稳定、容易陷入局部最优等问题&#xff0c;DCGAN相对于普通GAN的优点是能够生成更加逼真、清晰的图像。 因为DCGAN是在GAN的基础上的改造&#xff0c;所以本篇只针对GAN的改造点进行讲解&#xff0c;其…

Pytorch的hook函数

hook函数是勾子函数&#xff0c;用于在不改变原始模型结构的情况下&#xff0c;注入一些新的代码用于调试和检验模型&#xff0c;常见的用法有保留非叶子结点的梯度数据&#xff08;Pytorch的非叶子节点的梯度数据在计算完毕之后就会被删除&#xff0c;访问的时候会显示为None&…

RegSeg 学习笔记(待完善)

论文阅读 解决的问题 引用别的论文的内容 可以用 controlf 寻找想要的内容 PPM 空间金字塔池化改进 SPP / SPPF / SimSPPF / ASPP / RFB / SPPCSPC / SPPFCSPC / SPPELAN &#xfffc; ASPP STDC&#xff1a;short-term dense concatenate module 和 DDRNet SE-ResNeXt …

快速入门Axure RP:解答4个关键问题!

软件Axure RP 是一种功能强大的设计工具&#xff0c;用于使用 Web、移动和桌面应用程序项目创建交互原型。Axure RP软件中的 RP代表快速原型制作&#xff0c;这是软件Axure RP的核心特征。用户使用Axurere RP软件可以快速地将简单的想法创建成线框图和原型。Axure 因此&#xf…

实时数仓之实时数仓架构(Hudi)

目前比较流行的实时数仓架构有两类&#xff0c;其中一类是以FlinkDoris为核心的实时数仓架构方案&#xff1b;另一类是以湖仓一体架构为核心的实时数仓架构方案。本文针对FlinkHudi湖仓一体架构进行介绍&#xff0c;这套架构的特点是可以基于一套数据完全实现Lambda架构。实时数…

【二叉树】Leetcode 98. 验证二叉搜索树【中等】

验证二叉搜索树 给你一个二叉树的根节点 root &#xff0c;判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义如下&#xff1a; 节点的左子树只包含 小于 当前节点的数。节点的右子树只包含 大于 当前节点的数。所有左子树和右子树自身必须也是二叉搜索树。 示例1&a…

【Python函数和类2/6】函数的参数

目录 目标 为函数设置参数 传递实参 关键字实参 关键字实参的顺序 位置实参 常见错误 缺少实参 位置实参的顺序 默认值形参 参数的优先级 默认值形参的位置 总结 目标 上篇博客中&#xff0c;我们在定义函数时&#xff0c;使用了空的括号。这表示它不需要任何信息就…

浅谈C语言编译与链接

个人主页&#xff08;找往期文章包括但不限于本期文章中不懂的知识点&#xff09;&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 翻译环境和运行环境 在ANSI C&#xff08;标准 C&#xff09;的任何一种实现中&#xff0c;存在两个不同的环境。 第1种是翻译环境&#xff0c;在这个…

ssh 公私钥(github)

一、生成ssh公私钥 生成自定义名称的SSH公钥和私钥对&#xff0c;需要使用ssh-keygen命令&#xff0c;这是大多数Linux和Unix系统自带的标准工具。下面&#xff0c;简单展示如何使用ssh-keygen命令来生成具有自定义名称的SSH密钥对。 步骤 1: 打开终端 首先&#xff0c;打开我…

增强现实(AR)和虚拟现实(VR)营销的未来:沉浸式体验和品牌参与

--- 如何将AR和VR技术应用于营销&#xff0c;以提高品牌知名度、客户参与度 增强现实&#xff08;AR&#xff09;和虚拟现实&#xff08;VR&#xff09;不再只是游戏。这些技术为品牌与受众互动提供了创新的方式。营销人员可以创造更好的客户体验&#xff0c;并为身临其境的故…

hadoop-3.1.1分布式搭建与常用命令

一、准备工作 1.首先需要三台虚拟机&#xff1a; master 、 node1 、 node2 2.时间同步 ntpdate ntp.aliyun.com 3.调整时区 cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime 4.jdk1.8 java -version 5.修改主机名 三台分别执行 vim /etc/hostname 并将内容指定为…

电脑突然死机怎么办?

死机是电脑常见的故障问题&#xff0c;尤其是对于老式电脑来说&#xff0c;一言不合电脑画面就静止了&#xff0c;最后只能强制关机重启。那么你一定想知道是什么原因造成的吧&#xff0c;一般散热不良最容易让电脑死机&#xff0c;还有系统故障&#xff0c;比如不小心误删了系…

【实现报告】学生信息管理系统(顺序表)

目录 实验一 线性表的基本操作 一、实验目的 二、实验内容 三、实验提示 四、实验要求 五、实验代码如下&#xff1a; &#xff08;一&#xff09;顺序表的构建及初始化 &#xff08;二&#xff09;检查顺序表是否需要扩容 &#xff08;三&#xff09;根据指定学生个…

企业网站建设的方法的相关问题的解决办法的问题

现在市场上比较大的公司都建立了自己的企业网站&#xff0c;比如华为、小米等&#xff0c;在他们的企业网站中&#xff0c;可以充分展示自己产品的优势&#xff0c;介绍公司的优质服务。 这都是让顾客改变购买想法的重要因素。 现在互联网发达了&#xff0c;很多人在购买产品的…

详细分析axios.js:72 Uncaught (in promise) Error: 未知错误 的解决方法(图文)

目录 1. 问题所示2. 原理分析3. 解决方法1. 问题所示 调试接口的时候,打开一个网页,在终端出现如下错误: axios.js:72 Uncaught (in promise) Error: 未知错误at __webpack_exports__.default (axios.js:72:1)截图如下所示: 2. 原理分析 点击浏览器的Bug出错: // 如果…

C/C++语言学习路线: 嵌入式开发、底层软件、操作系统方向(持续更新)

初级&#xff1a;用好手上的锤子 1 【感性】认识 C 系编程语言开发调试过程 1.1 视频教程点到为止 1.2 炫技视频看看就行 1.3 编程游戏不玩也罢 有些游戏的主题任务就是编程&#xff0c;游戏和实际应用环境有一定差异&#xff08;工具、操作流程&#xff09;&#xff0c;在…

进程知识点

引用的文章&#xff1a;操作系统——进程通信&#xff08;IPC&#xff09;_系统ipc-CSDN博客 面试汇总(五)&#xff1a;操作系统常见面试总结(一)&#xff1a;进程与线程的相关知识点 - 知乎 (zhihu.com) 二、进程的定义、组成、组成方式及特征_进程的组成部分必须包含-CSDN博…

2024年北京事业单位报名照片要求,注意格式

2024年北京事业单位报名照片要求&#xff0c;注意格式
最新文章