c++11 auto类型推导的使用建议和注意事项

概述:

首先c++是强类型语言,也就是在定义变量的时候必须指定具体的类型。

像我们常用的int,float,char等等都是类型,auto关键字原本的意思是说明某个变量是自动变量,c++11提升了它的功能。

在c++11之后,我们可以使用auto来进行类型推导。

auto var1 = 1;     // int 
auto var2 = 1L;    // long
auto var3 = 1LL;   // long long
auto var4 = 4.2f;  // float
auto var5 = 4.2;   // double
auto var6 = 'a';   // char

auto stu  = Student();      //  Student   自定以类型

上面,我们使用auto自动推导出了各变量的类型,我们不需要自己手动去写变量的类型,auto就可以根据后面的数据推断出变量的类型。

其实,auto用起来很方便,它可以让我们不去使用具体的类型,但是滥用auto并不好。 

 auto使用的注意事项

  • auto相当于一个占位符,使用auto必须同时对相应的数据进行初始化
  •  auto无法推断出引用和const
    const int a = 10;
    auto b = a;             // 此时auto推断出的类型为int,但是a是const int 
    b = 10;                   // 我们可以被允许修改b中的值

    int &a1 = a;   
    auto b1 = a1;        // 此时auto推出的类型为int, 但是a是 int&

所以,如果我们使用auto,并且用const和&修饰变量:   const auto & b1  = a1; 

  • auto不能推断数组类型
    auto a[3] = {1,2,3};         // 这样写是错误的

  • auto不能用于模板类型推断
    vector<int> v1;
    vector<auto> v2 = v1;  

  • auto不能用于函数形参

  • auto不能用于类内部成员变量的推导

     
  • 不能使用auto推导虚函数的函数返回值

  

auto的使用建议 

建议:   
1.  遇到类型较长的类型的情况
2.  遇到无法得知具体是什么类型的情况

虽然auto很方便,可以帮助自动推导类型,但是使用它有好有坏。 

比如:  

std::string func() {
    return std::string();
}

main:
auto ret = func();                 // 这里使用auto自动推导出函数返回的类型。为string
std::cout << ret.size() << std::endl;   

这是当我们对函数进行修改之后,其返回了char*类型
char *func() {
    return std::string();
}


好处:   
因为函数的返回值类型变量,那么用于接受这个返回值的变量的类型也需要改变,但是我们使用了auto,我们就不需要自己去修改它的类型。当func的返回值改变之后auto会自动推导出来。   --   这显然很方便,我们不需要修改源代码。

坏处:
1. 函数func返回了string类型,然后我们使用返回值去调用string内部的函数size,但是当函数进行修改之后,auto推导出来的类型为char*,很显然char*根本没有那个函数,所以程序会报错。 --   如果你代码中多处用到返回值中的函数,会导致程序问题

2. 使用auto之后可读性变差了,因为如果你直接写std::string或者char*,阅读者很容易就知道这个变量的类型,以及返回值的类型。

如果你使用auto:  你得把光标放到变量上,vs的智能提示才可知道变量的类型,更或者我们得查看函数的声明或者定义才可以知道变量的类型。  --  这样很不直观

所以在正常的情况下是不建议使用auto关键字的。

那么应该什么时候使用?

看下面的情况:  

std::map<std::string, std::string> m1;
m1.emplace("好好","学习");

// 使用迭代器
for (std::map<std::string, std::string>::const_iterator it = m1.cbegin(); it != m1.cend(); it++) {

}

下面,我们是使用了迭代器去遍历我们的容器map的,你会发现使用迭代器类型的时候它的类型很长,显得代码很臃肿,这时候我们就可以使用auto关键字使得代码更加的整洁。
 

使用auto的for循环:

for (auto it = m1.cbegin(); it != m1.cend(); it++) {

}

很显然,这种写法更加的整洁。

当然了,这只是一种写法,你也可以使用c++11新增的for循环来遍历容器。

 
所以,我们应该在类型比较长的时候,或者我们不知道使用的是什么类型的时候可以选择使用auto。


其实,对于长类型你可以拥有另外一种选择:

using const_iterator = std::map<std::string, std::string>::const_iterator;
typedef std::map<std::string, std::string>::const_iterator const_iterator;


// 使用迭代器
for (const_iterator it = m1.cbegin(); it != m1.cend(); it++) {

}
 

我们使用using和typedef(c++11之前使用),用一个较短的类型名替换了长度较长的类型名。

(对于长类型,使用auto还是给类型定义别名的方式,看自己的选择)

c++14新增的auto关键字功能(函数返回值)

1. 在c++14之后,我们可以使用auto来推导出函数的返回值类型(根据函数的返回值) -- 可用于函数模板的返回值


auto func1(){         // auto会推断出此函数返回int类型。
    return 1;
}

auto func(){          // 返回值为void

}

注意: 
这种场景下,如果函数有多个分支需要返回值,那么需要保证多个分支的返回值应该是一样的。比如:

auto func() {
    bool ret = true;

    if (!ret)
        return 1.1;
    else
        return 1;       // error,因为两个分支的返回类型不同
}




2. c++14之后我们还可以将auto使用在函数声明的返回值中
比如: 
auto func2();                // 函数func2的声明, auto会根据函数的定义推断出其返回值

但是,注意其函数定义的返回值也必须为auto,否则会被认为是函数的重载形式。

所以func2的定义为:                      // 最后返回值类型推断为double
auto func2(){
    return 1.0;                     
}

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

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

相关文章

STM32F1之OV7725摄像头

目录 1. 摄像头简介 2. OV7725 摄像头简介 3. OV7725 引脚 4. OV7725 功能框架图 5. SCCB时序 5.1 SCCB 的起始、停止信号及数据有效性 5.2 SCCB 数据读写过程 1. 摄像头简介 在各类信息中&#xff0c;图像含有最丰富的信息&#xff0c;作为机…

SVM原问题与对偶问题

目的&#xff1a;求出我们的f(X)&#xff0c;它代表着我们X映射到多维的情况&#xff0c;能够帮我们在多维中招到超平面进行分类。 1.优化问题&#xff1a; 1.1推荐好书&#xff1a; 1.2 优化理论中的原问题&#xff1a; 原问题和限制条件如下&#xff1a; 这是一个泛化性…

MATLAB算法实战应用案例精讲-【数模应用】KANO模型

目录 前言 发展历程 几个相关概念 算法原理 什么是KANO模型?

【漏洞复现】英飞达医学影像存档与通信系统 WebJobUpload 任意文件上传漏洞

0x01 产品简介 英飞达医学影像存档与通信系统 Picture Archiving and Communicaton System&#xff0c;它是应用在医院影像科室的系统&#xff0c;主要的任务就是把日常产生的各种医学影像(包括核磁&#xff0c;CT&#xff0c;超声&#xff0c;各种X光机&#xff0c;各种红外仪…

LeetCode - 数组 - 四数之和

题目地址 描述 给你一个由 n 个整数组成的数组 nums &#xff0c;和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] &#xff08;若两个四元组元素一一对应&#xff0c;则认为两个四元组重复&#xff09;&#x…

python从入门到精通02

一、平均油耗计算 total float(input("请输入加油的总金额&#xff1a;")) kilometers int(input("请输入行驶的总里程&#xff1a;")) average total / kilometers print("平均油耗是&#xff1a;", average,"元/公里") 二、华氏…

删除当前磁盘空文件夹小工具

删除当前磁盘空文件夹小工具 chcp 65001 >nulecho off setlocal EnableDelayedExpansionecho 正在扫描空文件夹&#xff0c;请稍候...for /f "delims" %%d in (dir /ad /b /s "\*") do (set "folder%%d"dir /a /b "!folder!" | fi…

个人学习之路

大学的时候在学校学习的是java&#xff0c;没有兴趣&#xff0c;且罢 快毕业了&#xff0c;为了工作学了C和C&#xff0c;每每也是在煎熬之中度过&#xff0c;总是否定自己&#xff0c;想要放弃又重新拾起来&#xff0c;做了相关的工作 后面换了工作&#xff0c;转到了python…

Spring IOC深度解析:IOC容器的原理与高级特性详解

1. Spring IOC容器概述 Spring框架是Java企业级应用开发中的重量级选手&#xff0c;其中IOC&#xff08;控制反转&#xff09;是其核心功能之一。通过引入IOC容器&#xff0c;Spring改变了对象的创建方式及其依赖关系的管理&#xff0c;进而带来了应用程序设计的革命。 1.1 什…

cs与msf权限传递以及mimikatz抓取win2012明文密码

简单的介绍 cs与msf的简单介绍 我查找过资料得出&#xff0c;Cobalt Strike 的前身是 Armitage&#xff0c;而 Armitage 又可以理解为 Metasploit Framework 的图形界面版&#xff0c;因此 Cobalt Strike 与 Metasploit Framework 在很多地方都是兼容的&#xff0c;所以我们便…

【电子信息(工程)】电子通信创新创业教育综合

电子通信创新创业教育 阐述电磁场、电磁波和电磁频谱及应用一、电磁场 法拉第根据电流与磁场的关系,提出了电磁感应定律:如果电磁场中有处于运动状态下的闭合回路导体存在,流经该导体磁场的磁场强度和磁场量,通常都会出现相应的变化,电磁感应电流由此而产生。随后,英国的…

人工智能 框架 paddlepaddle 飞桨 使用指南 使用例子 线性回归模型demo 详解

安装过程&使用指南&线性回归模型 使用例子 本来预想 是安装 到 conda 版本的 11.7的 但是电脑没有gpu 所以 安装过程稍有变动,下面简单讲下 conda create -n paddle_env117 python=3.9 由于想安装11.7版本 py 是3.9 所以虚拟环境名称也是 paddle_env117 activa…

下载和安装AD19 - Altium Designer 19.1.9 Build 167

虽然有AD24 的安装资源&#xff0c;但是我比较喜欢19 这个数字[doge] 下载 仍然是从毛子网站源头进货&#xff1a;https://rutracker.net/forum/viewtopic.php?t5754276&#xff0c;网盘: https://pan.baidu.com/s/1ic31N4h7HS2FBu7JFll0YQ?pwdvjum 提取码: vjum 安装 压…

如何用pyecharts工具制作地图

# # 导入地图构建使用的包 # from pyecharts.charts import Map # from pyecharts.options import VisualMapOpts # # # 创建一个地图 # China_map Map() # # # 给地图准备数据 # data [ # ("北京市", 100), # ("上海市", 95), # ("深圳…

【DevOps】深入了解RabbitMQ:AMQP协议基础、消息队列工作原理和应用场景

目录 一、核心功能 二、优势 三、核心概念 四、工作原理 五、交换机类型 六、消息确认 七、持久性和可靠性 八、插件和扩展 九、集群和镜像队列 十、客户端库 十一、管理界面 十二、应用场景 RabbitMQ是一个基于AMQP协议的消息队列中间件&#xff0c;提供高可用、可…

[MRCTF2020]Xor

32位程序 主要逻辑 flagMSAWB~FXZ:J:tQJ"N bpdd}8g for i in range(len(flag)):print(chr(ord(flag[i])^i),end)

react 权限树形结构实现

项目背景 react ant design 实现效果 1 将后台返回的平铺数据 , 转成树形结构 const [roleId, setRoleId] useState() //存储角色id// 弹权限弹窗const empowerHandle async record > {setRoleId(record.roleId)//获取单独的权限const res1 await getPermission({ role…

Java中线程调度与进程调度全解析

1.线程调度与进程调度的基本概念 1.1 什么是线程调度 线程调度是计算机多线程操作系统中分配CPU时间给各个线程的过程。每个线程代表程序中的一个执行路径&#xff0c;操作系统通过线程调度器分配处理器时间&#xff0c;决定哪个线程将获得执行的机会&#xff0c;以及获得的时…

力扣96. 不同的二叉搜索树

Problem: 96. 不同的二叉搜索树 文章目录 题目描述思路复杂度Code 题目描述 思路 一个数字做根节点的话可能的结果为&#xff1a;其左边数字做子树的组合数字乘以其右边数字做子树的个数之积 1.创建备忘录memo&#xff1b; 2.递归分别求取当前数字左边和右边数字做子树的数量&…

Vue 中 diff 算法原理

1. Diff 概念 vue 基于虚拟 DOM 做更新 。diff 的核心就是比较两个虚拟节点的差异 。Vue 的 diff 算法是平级比较,不考虑跨级比较的情况。内部采用深度递归的方式 + 双指针的方式进行比较。 2. Vue2 Diff 比较流程. 1.1先比较是否是相同节点 key tag 1.2相同节点比较属性,并…