掘根宝典之C++类型别名,关键字typedef,auto,decltype

类型别名

在C++中,我们可以使用typedef关键字或using关键字来创建类型别名。下面是两种方式的示例:

  1. 使用typedef关键字创建类型别名:
typedef int myInt;
typedef float myFloat;myInt a;//等价int a;
myFloat b;//等价float b;

  1. 使用using关键字创建类型别名:
using myInt = int;
using myFloat = float;myInt a;//等价int a;
myFloat b;//等价float b;

使用类型别名可以方便地重命名现有的类型,以提高代码的可读性和灵活性。例如,我们可以使用以下方式创建一个类型别名来代替std::vector<int>

using IntVector = std::vector<int>;
IntVector myVector;

注意点

我们在使用类型别名的时候,要特别注意将类型别名用于指针

我们先看个例子

我们发现啊,这个第二行这句还没编译就已经显示有错误了,这是为什么呢?

这是因为遇到使用类型别名的声明语句的时候,人们总是错误的尝试把类型别名替换为它本来的样子,也就是说我们把这下面两句话视作等效的

const A b="asss";
const char*b="asss";

但是事实并不是如此。

A实际上是指向char的指针,因此,const A就是指向char的常量指针,而非指向常量字符的指针。

也就是说,下面这两句是等效的

	const A b = "asss";;char* const a = "asss";

我们再总结一下 

声明语句中用到A时,其基本数据类型是指针。

可是用char*重写了声明语句后,数据类型就变成了char,*成了声明符的一部分。这样改写的结果是,const char成了基本数据类型 

前后两种声明意义截然不同,前者声明了一个指向char的常量指针,改写后的形式则声明了一个指向const char的指针

关键字auto

在C++中,关键字auto用于自动推导变量的类型。也就是说,编译器会根据变量的初始化值来确定变量的类型。

显然auto定义的变量必须要有初始值。

定义的具体语法如下:

auto variable = value;

其中variable是变量名,value是初始化值。

例如,以下是使用auto定义变量的示例:

auto x = 10; // 推导x的类型为int,初始化为10
auto str = "Hello"; // 推导str的类型为const char*
auto vec = std::vector<int>(); // 推导vec的类型为std::vector<int>
auto sum = [](int a, int b) { return a + b; }; // 推导sum的类型为lambda表达式类型

在这些例子中,编译器会根据变量的初始化值自动推导出变量的类型,并将其赋值给相应的变量。

使用auto也可以在一条语句中声明多个变量。因为一条声明语句只能有一个基本数据类型,所以该语句中所有变量的初始数据类型都必须一样

int a=9;
auto i=0,*p=&a;//正确,i是int型,p是int*型
auto b=0,c=9.0;//不正确,b和c的类型不正确

复合类型,常量和auto

编译器推断出来的auto类型有时候和初始值的类型并不完全一样,编译器会适当地改变结果类型使其更符合初始化规则。

第一点

首先,正如我们所熟知的,使用引用其实是使用引用的对象特别是当引用被用作初始值时,真正参与初始化的其实是引用对象的值。

此时编译器以引用对象的类型作为auto的类型:

int i=0,&r=i;
auto a=r;//a是一个整数(r是i的别名,而i是一个整数)

 也就是说,上面这些语句就等价于下面这个

int i=0,&r=i;
int a=i;
解决方法 

那我们怎么使用auto来用于引用呢?

很简单,直接在auto后面加一个&就行了

int i=0,&r=i;
auto &a=i;

第二点

auto一般会忽略掉顶层const,同时保留底层const

什么意思呢?我们来看看一些例子

例子1
	int i = 9;const int ci = i, & cr = ci;auto b = ci;//等价int b=i;auto c = cr;//等价int c=i;

我们可能会好奇

为啥b不是const int类型?c为啥不是const int&类型?

因为ci的顶层const特性被忽略掉了 ,c也是同样的道理

如果我们需要将b,c保留顶层const特性,则需要明确指出

	int i = 9;const int ci = i, & cr = ci;const auto b = ci;//等价const int b=i;const auto c = cr;//等价const int c=i;

例子2

我们再看一个例子

int i = 9;
const int ci = i, & cr = ci;
auto d = &i;//等价int* d=&i;
auto e = &ci;//等价const int*e=&ci;

 

那为啥e就是const int*类型?

这是因为对常量对象取地址是一种底层const,会被保留下来

注意事项

以下是一些关于auto关键字的注意事项:

  1. auto只能用于自动推导变量的类型,不能用于函数的返回值、函数参数或非静态成员变量的类型。

  2. 自动推导的类型将根据变量的初始化值进行推导。如果变量的初始化值不明确或不唯一,编译器将会报错。

  3. auto关键字可以与const&等类型修饰符一起使用。例如:auto const&表示自动推导一个const引用。

  4. 当使用auto推导出的类型是一个模板类型时,编译器会根据变量的初始化值推导出具体的模板类型。

  5. 当使用auto推导出的类型是迭代器时,需要确保变量的初始化值是一个可迭代的容器,否则会导致编译错误。

  6. 自动推导类型的变量在编译时期确定类型,无法在运行时期更改类型。

总而言之,auto关键字是一个方便的特性,可以根据初始化值自动推导变量的类型,减少了显式类型声明的冗余。但需要注意,过度使用auto可能会降低代码的清晰度和可读性,所以在选择使用auto时,要谨慎权衡代码的简洁性和可读性。

关键字decltype

有的时候,我们希望从表达式的类型推断出要定义的变量的类型,但是不是想用该表达式的值初始化变量。

为了满足这种情况,C++11引入了关键字decltype,它的作用是选择并返回操作数的数据类型。在此过程中,编译器分析表达式并得到它的类型,却不实际计算表达式的值。

我们看个例子

decltype(f()) sum=x;//sum的类型就是f()返回值的类型

编译器并不实际调用函数f,而是使用当调用发生时f的返回值类型作为sum的类型。

换句话说,编译器为sum指定的类型是什么呢?就是假如f被调用的话将会返回的那个类型。

decltype和顶层const,引用

decltype处理顶层const和引用的方式与auto有些许不同。

如果decltype使用的表达式是一个变量,则decltype返回该变量的类型(包括顶层const 和引用在内):

const int ci = 0, &cj=ci;
decltype(ci)x=0; //x的类型是const int
decltype(cj) y= x; //y的类型是const ints,y绑定到变量x
decltype(cj)z; //错误:z是一个引用,必须初始化


因为cj是一个引用,decltype(cj)的结果就是引用类型,因此作为引用的z必须被初始化。

需要指出的是,引用从来都作为其所指对象的同义词出现,只有用在decltype处是一个例外,decltype直接给一个引用类型

decltype 和引用

如果decltype使用的表达式不是一个变量,则decltype返回表达式结果对应的类型。

有些表达式将向decltype返回一个引用类型。

一般来说当这种情况发生时,意味着该表达式的结果对象能作为一条赋值语句的左值:

// decltype 的结果可以是引用类型
int i=42, *p= &i, &r = i;decltype(r + 0) b; //正确:加法的结果是int,因此b是一个(未初始化的)intdecltype(*p) c; // 错误:c是int&,必须初始化


因为r是一个引用,因此decltype(r)的结果是引用类型。

如果想让结果类型是x所指的类型,可以把x作为表达式的一部分,如r+0,显然这个表达式的结果将是一个具体值而非一个引用。

另一方面,如果表达式的内容是解引用操作,则decltype 将得到引用类型。正如我们所熟悉的那样,解引用指针可以得到指针所指的对象,而且还能给这个对象赋值。因此,decltype(*p)的结果类型就是int&,而非int。

特殊情况

有一种情况需要特别注意:对于decltype 所用的表达式来说,如果变量名加上了一对括号,则得到的类型与不加括号时会有不同。

如果decltype 使用的是一个不加括号的变量,则得到的结果就是该变量的类型;

如果给变量加上了一层或多层括号,编译器就会把它当成是一个表达式。变量是一种可以作为赋值语句左值的特殊表达式,所以这样的decltype就会得到引用类型:

// decltype的表达式如果是加上了括号的变量,结果将是引用
decltype((i)) d; /1 错误:d是int&,必须初始化
decltype(i) e; // 正确:e是一个(未初始化的)int


切记:decltype((variable))(注意是双层括号)的结果永远是引用,而 decltype(variable)结果只有当 variable 本身就是一个引用时才是引用。

decltype和auto的区别

autodecltype是C++11引入的两个关键字,用于类型推导和类型查询。它们的区别如下:

  1. auto用于自动推导变量的类型,而decltype用于获取表达式的类型。

  2. auto在编译时期根据初始化表达式推导出变量的类型,而decltype在编译时期查询表达式的类型,不会执行表达式。

  3. auto可以用于初始化变量,而decltype不能直接用于变量的初始化。

  4. auto可以推导出值类型、指针类型、引用类型等,而decltype更灵活,可以推导出表达式的类型,包括值类型、指针类型、引用类型、函数类型等。

下面是一些示例来说明它们的区别:

int x = 10;
auto a = x; // 推导出a的类型为int
decltype(x) b = x; // 查询x的类型,b的类型为intint& y = x;
auto c = y; // 推导出c的类型为int,而不是int&
decltype(y) d = y; // 查询y的类型,d的类型为int&int foo(int a, int b);
auto result = foo(1, 2); // 推导出result的类型为函数返回类型
decltype(foo(1, 2)) e = foo(1, 2); // 查询foo(1, 2)的类型,e的类型为int

总而言之,auto用于方便地推导变量的类型,而decltype用于查询表达式的类型。在实际使用中,根据需要选择合适的关键字。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

javase day03笔记

第三天课堂笔记 idea的使用★★★ 创建空工程创建模块创建包&#xff1a;package创建类idea的设置 file -> settings 快捷键 shift &#xff0b; 回车 &#xff1a; 光标切换到下一行psvm回车&#xff1a; main方法main回车&#xff1a;main方法sout回车&#xff1a;输…

Skia最新版CMake编译

运行示例&#xff1a;example/HelloWorld.cpp Skia: 2024年03月08日 master分支: 993a88a663c817fce23d47394b574e19d9991f2f 使用CMake编译 python tools/git-sync-depsbin/gn gen out/config --idejson --json-ide-script../../gn/gn_to_cmake.py此时output目录会生成CM…

微信小程序-分包

分包 1.什么是分包 分包指的是把一个完整的小程序项目&#xff0c;按照需求划分为不同的子包&#xff0c;在构建时打包成不同的分包&#xff0c;用户在使用时按需进行加载。 2.分包的好处 对小程序进行分包的好处主要有以下两点&#xff1a; 可以优化小程序首次启动的下载时间…

数据结构入门(3)2.链表接口实现

目录 前言 头文件 动态申请一个结点 单链表打印 单链表尾插 单链表的头插 单链表的尾删 单链表头删 单链表查找 单链表在pos位置之后插入x 单链表删除pos位置之后的值 在pos的前面插入 删除pos位置 销毁顺序表 前言 本文将介绍链表常见的功能的实现 头文件 #…

《互联网的世界》第六讲-去中心化和安全

互联网构建于开放互联的中立原则之上&#xff0c;公平接入&#xff0c;数据互联互通&#xff0c;流量被无差别对待&#xff0c;这意味着互联网本质上是匿名&#xff0c;去中心的&#xff0c;这与我们的现实世界完全不同。 但互联网上的主流业务却是 c/s 产销模式&#xff0c;试…

JAVA实战开源项目:校园失物招领管理系统(Vue+SpringBoot)

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容2.1 招领管理模块2.2 寻物管理模块2.3 系统公告模块2.4 感谢留言模块 三、界面展示3.1 登录注册3.2 招领模块3.3 寻物模块3.4 公告模块3.5 感谢留言模块3.6 系统基础模块 四、免责说明 一、摘要 1.1 项目介绍 校园失物招领…

STM32CubeIDE基础学习-STM32CubeIDE软件偏好设置

STM32CubeIDE基础学习-STM32CubeIDE软件偏好设置 文章目录 STM32CubeIDE基础学习-STM32CubeIDE软件偏好设置前言第1章 设置字体颜色第2章 设置字体大小第3章 设置代码区背景颜色总结 前言 编程软件环境最好就设置一个自己喜欢的界面进行显示&#xff0c;这样看起来会比较舒服些…

026—pandas 根据文本数据提取特征

前言 在数据处理中&#xff0c;源数据可能具有一定便于记录但又复杂的结构&#xff0c;我们在后续使用数据时还需要进一步进行处理。在本例中&#xff0c;要根据一列数据提取出数据中的相关特征&#xff0c;我们来看看 pandas 是如何完成的。 需求&#xff1a; 以上数据的 a …

CKB转型为BTC Layer2后月涨超 300%,还有哪些转型热门赛道的老项目?

虽然说牛市下&#xff0c;炒新不炒旧。但一些渡过漫长熊市的老牌项目方&#xff0c;重新回到牌桌前开始新叙事后&#xff0c;市场依然有人买单。 部分项目方已经初步尝到了甜头&#xff0c;Arweave&#xff08;AR&#xff09;宣布从去中心化数据存储转换到「以太坊杀手」后&am…

网络攻防中nginx安全配置,让木马上传后不能执行、让木马执行后看不到非网站目录文件、命令执行后权限不能过高

网络攻防中nginx安全配置,让木马上传后不能执行、让木马执行后看不到非网站目录文件、命令执行后权限不能过高。 0x01 Nginx介绍 nginx本身不能处理PHP,它只是个web服务器,当接收到请求后,如果是php请求,则发给php解释器处理,并把结果返回给客户端。nginx一般是把请求发…

腾讯qlv格式转换mp4,亲测可解决,免费领取

问题描述 最近想兼职做自媒体,最初想法是想把腾讯视频上的资源下载到本地,本地做一些剪辑和图文配音发布到自媒体app上,但是我还是幼稚了,下载到腾讯的视频居然是qlv加密的,用自带的腾讯视频才能看,网上找了一大堆转换方法,全是广告,什么cmd进去用命令行转的,什么找到…

大数据 - Spark系列《十三》- spark集群部署模式

Spark系列文章&#xff1a; 大数据 - Spark系列《一》- 从Hadoop到Spark&#xff1a;大数据计算引擎的演进-CSDN博客 大数据 - Spark系列《二》- 关于Spark在Idea中的一些常用配置-CSDN博客 大数据 - Spark系列《三》- 加载各种数据源创建RDD-CSDN博客 大数据 - Spark系列《…

五、OpenAI实战之Assistants API

在8线小城的革委会办公室里&#xff0c;黑8和革委会主任的对话再次展开。 黑8&#xff1a;主任&#xff0c;您知道吗&#xff1f;除了OpenAI API&#xff0c;现在还有一项新的技术叫做Assistants API&#xff0c;它可以帮助我们更好地进行对话和沟通。 主任&#xff1a;Assis…

Java网络编程详解

目录 网络编程 1、概述 2、网络通信的要素 3、IP 4、端口 5、通信协议 6、TCP 文件上传 Tomcat 7、UDP 单方发送单方接受 双方发送接收 8、URL URL测试 URL下载网络资源 网络编程 1、概述 信件&#xff1a; 计算机网络&#xff1a; 计算机网络是指将地理位置不…

WPF —— TextBlock、LineBreak RadioButton控件详解

一:TextBlock 1&#xff1a;TextBlock 简介 <LineBreak/> 换行 显示文本 标签内容和content属性共存 2、TextBlock 常用的属性 Foreground&#xff1a;TextBlock的文本内容的颜色。 Background&#xff1a;背景&#xff0c;获取或设置要用于填充内容区域背景的 Brush…

冒泡排序的理解与实现【C语言、C++、java】

冒泡排序介绍 冒泡排序(Bubble Sort)&#xff0c;又被称为气泡排序或泡沫排序。 它是一种较简单的排序算法。它会遍历若干次要排序的数列&#xff0c;每次遍历时&#xff0c;它都会从前往后依次的比较相邻两个数的大小&#xff1b;如果前者比后者大&#xff0c;则交换它们的位…

一体机电脑辐射超标整改

电脑一体机是目前台式机和笔记本电脑之间的一个新型的市场产物&#xff0c;它将主机部分、显示器部分整合到一起的新形态电脑&#xff0c;该产品的创新在于内部元件的高度集成。随着无线技术的发展&#xff0c;电脑一体机的键盘、鼠标与显示器可实现无线链接&#xff0c;机器只…

美国站群服务器使用技巧与注意事项

美国站群服务器使用技巧与注意事项有哪些?RAKsmart小编为您整理发布美国站群服务器使用技巧与注意事项&#xff0c;希望对您有帮助。 美国站群服务器的使用技巧主要包括远程管理、灵活配置和备份还原&#xff0c;具体如下&#xff1a; 1. **远程管理**&#xff1a;用户可以通过…

计算机网络-第5章 运输层(2)

5.6 TCP可靠传输实现 以字节为单位的滑动窗口。 发送窗口已满&#xff0c;停止发送。 发送和接收的数据都来自缓存。 超时重传时间RTO选择&#xff1a;自适应算法&#xff0c; 选择确认SACK&#xff1a;只传送缺少的数据。大多数实现还是重传所有未被确认的数据块。 5.7 TCP的…

LLM 推理优化

LLM 推理服务重点关注两个指标&#xff1a;吞吐量和时延&#xff1a; 吞吐量&#xff1a;主要从系统的角度来看&#xff0c;即系统在单位时间内能处理的 tokens 数量。计算方法为系统处理完成的 tokens个数除以对应耗时&#xff0c;其中 tokens 个数一般指输入序列和输出序列长…