C++11: auto 关键字

news2024/9/20 21:47:32

目录

  • **前言**
  • **1. 推导规则**
  • **2. 不能使用 auto 的场景**
  • **3. 常见的使用场景**

前言

在 C++11 以前,auto 关键字的语义继承自 C 语言,表示 进入块后,自动分配内存,即分配堆栈内存。也就是说 auto 只能用于函数内,然而函数内部的声明变量默认使用的就是这种分配,因此在 C++11 以前,auto 关键字几乎没什么用处。
而在 C++11 以后,auto 关键字被赋予了新的语义:自动类型推导

auto 与 decltype 作用类似,但有一定的区别


1. 推导规则

语法:auto 变量名 = 变量值

auto 只是类型的 “占位符”,不是一个实际类型,它需要被编译器推导出来,因此:auto 声明的变量必须初始化,在编译时 auto 被真正的类型给替换掉。

推导规则满足:
当 表达式右部 的类型为

  • 一般类型 (非指针、非引用):auto 就是对应的类型,但 顶层 const 被忽略

    如果你对 顶层与底层 const 不了解的,可见文章:【C++ const 详解】 的第 4 部分。

    int 	  a  = 0;
    const int ca = a;
    ----------------------------------------
    auto x = 0;		// auto: int
    auto x = 1.0;	// auto: double
    auto x = 'a';	// auto: char
    auto x = a;		// auto: int
    auto x = ca;	// auto: int (顶层 const 被忽略)
    
  • 指针类型顶层 const 忽略,底层 const 不忽略保留指针类型
    int  a = 0;
    int* p = 0;
    
    const int* cp = &a;
    int* const pc = &a; 
    ---------------------------------------
    auto x = p;		// auto: int*
    auto x = cp;	// auto: const int*	(底层 const 不忽略)
    auto x = pc;	// auto: int* (顶层 const 忽略)
    
  • 引用类型:引用被忽略,const 不保留
    int   a  = 0;
    int&  lr = a;
    int&& rr = 0;
    
    const int&  clr = a;
    const int&& crr = 0; 
    -----------------------------------
    auto x = lr;	// auto: int (引用被忽略)
    auto x = rr;	// auto: int
    auto x = clr;	// auto: int (引用被忽略,const 不保留)
    auto x = crr;	// auto: int
    

volatile 关键字也满足上述规则中的 const 的规则

既然对于引用类型:引用 与 const 都被忽略,如果我们需要保留,那就需要手动指定。但是注意:auto 的推导仍然满足上面的推导过程

【例】const auto& x = a; (int&& a = 0;)
【解】auto: int;故在编译时 auto 被替换为 int (auto 只是占位符),那么上述语句相当于:const int& x = a,因此 x 的类型为 const int&。

在这里插入图片描述

【注】 引用是 右值引用 时,需要注意 引用折叠 问题,详情可见文章:【右值引用】 中的 4.1 部分。

也就是说,auto 在编译时先被编译器通过表达式右部的类型推导出来,并替换掉,而后 auto 修饰的变量的最终类型为 手动指定的类型 + auto 的实际类型。

但是 auto 并非时万能的,其中一个重要原因是:auto 是编译时推导


2. 不能使用 auto 的场景

  • 不能指定为 函数参数 的类型。

    可以这么理解:auto 是再编译时推导的,但是函数形参需要在函数被调用时,也就是运行时,才能被确定

    void fun(auto x);	// 错误
    
  • 对于类的成员,只能用于指定 非静态 const 成员 的类型。
    class A
    {
    	auto a = 0;	// 错误
    	static auto b = 0;	// 错误
    	static const auto c = 0;	// 正确 
    };
    
  • 无法定义数组
    int arr[] = { 0, 1, 2 };
    auto x   = arr;		// auto: int*
    auto x[] = arr;		// 错误
    auto x[] = { 0, 1, 2 };		// 错误
    
  • 无法利用 auto 推导模板类型
    template <typename T>
    class Test { };
    
    Test<int>  t;
    Test<auto> tt = t;	// 错误:无法推导 auto 的类型
    

那么什么时候比较合适使用 auto 呢?


3. 常见的使用场景

  • STL 容器的遍历
    • 不使用 auto 遍历,那么迭代器的类型会比较长:
    vector<int, vector<int>> t;
    vector<int, vector<int>>::iterator it = t.begin();
    for (; it != t.end(); it++) {}
    
    • 使用 auto 可以大大降低代码长度
    vector<int, vector<int>> t;
    for (auto it = t.begin(); it != t.end(); it++) {}
    
  • 模板中指定不确定函数的返回值类型
    在模板编程中,有时会出现着这种情况,在不同类中,统一函数,但是返回值不同(这种设计有点不合常理,但是可能存在)
    class A 
    {	
    	int fun();
    };
    
    class B
    {	
    	string fun();
    };
    // 两个 fun 返回值类型不同
    // 模板函数 f 中可能会调用 A、B 中的 fun 函数 
    template <typename T>
    void f(T t)
    {
    	// int x = t.fun();
    	// 还是 string x = t.fun();
    	// 如果指定为 int ;,那么当传入的 T = B 时,会报错:因为 B::fun() 返回值是 string
    	// 那么可以如下指定:
    	auto x = t.fun();
    	// ... ...
    }
    
  • … …

它的使用场景有许多,这取决于编写代码者自己本身,但是需要注意:在符合 auto 使用规则的前提下,如果程序大片的使用 auto,这可能使得代码可读性很差。


本文如有错误,欢迎批评指正。

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

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

相关文章

昇思25天学习打卡营第14天|基于MindNLP+MusicGen生成自己的个性化音乐

MusicGen是由Meta AI的团队开发出的一种音乐生成模型&#xff0c;它用一个语言模型来根据文本描述或音频提示制作音乐。这个模型分三步工作&#xff1a;首先&#xff0c;把用户给的文本转换成一系列状态&#xff1b;然后&#xff0c;用这些状态来预测音乐的音频token&#xff1…

[HTML]一文掌握

背景知识 主流浏览器 浏览器是展示和运行网页的平台&#xff0c; 常见的五大浏览器有 IE浏览器、火狐浏览器&#xff08;Firefox&#xff09;、谷歌浏览器&#xff08;Chrome&#xff09;、Safari浏览器、欧朋浏览器&#xff08;Opera&#xff09; 渲染引擎 浏览器解析代码渲…

【Linux 15】进程间通信的方式 - 管道

文章目录 &#x1f308; 一、管道介绍&#x1f308; 二、匿名管道⭐ 1. 匿名管道的概念⭐ 2. 匿名管道的创建⭐ 3. 匿名管道的本质⭐ 4. 匿名管道的使用⭐ 5. 匿名管道的特点⭐ 6. 匿名管道的大小 &#x1f308; 三、命名管道⭐ 1. 命名管道的概念⭐ 2. 命名管道的创建⭐ 3. 命…

USB转多路UART - USB 基础

一、 前言 断断续续做了不少USB相关开发&#xff0c;但是没有系统去了解过&#xff0c;遇到问题就很被动了。做这个USB转UART的项目就是&#xff0c;于是专门花了一天的时间学习USB及CDC相关&#xff0c;到写这文章时估计也忘得差不多了&#xff0c;趁项目收尾阶段记录一下&am…

OLAP引擎之Kylin

Apache Kylin 是一个开源的分布式分析引擎&#xff0c;设计用于在大数据环境中实现极快的在线分析处理 (OLAP) 查询。它主要用于解决大数据分析中的性能问题&#xff0c;并为大规模数据提供交互式的查询体验。Kylin 是由 eBay 于 2014 年开源的&#xff0c;现由 Apache 基金会管…

某直聘每日算法变更分析

带大家分析一下每日算法的变更情况如何破解&#xff1a; 1. 找到算法起始点 前面都是字符串的拼接&#xff0c;可以不用管&#xff0c;重点我们看数组的操作 af0d473b.js:11950 S: 191 e: 3 : af0d473b.js:11326 gl: 1 G: 1 : af0d473b.js:11950 S: 60 e: 3 : af0d473b.js:113…

Java 写一个可以持续发送消息的socket服务端

前言 最近在学习flink, 为了模仿一个持续的无界的数据源, 所以需要一个可以持续发送消息的socket服务端. 先上效果图 效果图 socket服务端可以持续的发送消息, flink端是一个统计单词出现总数的消费端,效果图如下 源代码 flink的消费端就不展示了, 需要引入一些依赖和版本…

多态性概念 OOPS

大家好&#xff01;今天&#xff0c;我们将探讨面向对象编程 (OOP) 中的一个基本概念 - 多态性。具体来说&#xff0c;我们将重点介绍其三种主要形式&#xff1a;方法重载、方法覆盖和方法隐藏。对于任何使用 OOP 语言&#xff08;例如 C#&#xff09;的程序员来说&#xff0c;…

嵌入式人工智能(17-基于树莓派4B的电机控制-伺服电机SG90)

伺服电机主要适用于角度需要不断变化且可以保持的控制系统&#xff0c;常见的机械臂、多足机器人、遥 控船、摄像头云台等都可以使用伺服电机来实现。 1、简介 伺服电动机又被称为执行电动机、舵机&#xff0c;如图9.4所示&#xff0c;是由直流电机、减速齿轮组、电位器和控制…

C语言 | Leetcode C语言题解之第264题丑数II

题目&#xff1a; 题解&#xff1a; int nthUglyNumber(int n) {int dp[n 1];dp[1] 1;int p2 1, p3 1, p5 1;for (int i 2; i < n; i) {int num2 dp[p2] * 2, num3 dp[p3] * 3, num5 dp[p5] * 5;dp[i] fmin(fmin(num2, num3), num5);if (dp[i] num2) {p2;}if (d…

Fastgpt接入ChatTTS本地AI语音合成模型实现语音实时朗读

前言 FastGPT 默认使用了 OpenAI 的 LLM 模型和语音合成模型,如果想要私有化部署的话,可以使用开源TTS项目f封装成兼容open ai的协议兼容的API接口。参考文章 《ChatTTS-一款适用于日常对话的AI生成式语音模型》 FastGPT接入本地AI语音TTS Base Url为你部署本地语音识别web…

Shell程序设计

各位看官&#xff0c;从今天开始&#xff0c;我们进入新的专栏Shell学习&#xff0c;Shell 是操作系统的命令行界面&#xff0c;它允许用户通过输入命令与操作系统交互。常见的 Shell 有 Bash 和 Zsh&#xff0c;它们可以执行用户输入的命令或运行脚本文件。Shell 广泛应用于系…

Google AI加速代码迁移

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

知名的GPU算力租用平台,适合进行大规模深度学习训练

目录 引言 GPU算力租用的重要性 当前市场趋势 选择GPU算力平台的关键因素 知名的GPU算力租用平台&#xff0c;适合进行大规模深度学习训练 引言 在数字时代&#xff0c;计算能力是推动科技创新的核心驱动力&#xff0c;尤其是在人工智能&#xff08;AI&#xff09;、机器学…

【ARM】SMMU系统虚拟化整理

目录 1.MMU的基本介绍 1.1 特点梳理 2.功能 DVM interface PTW interface 2.1 操作流程 2.1.1 StreamID 2.1.2 安全状态&#xff1a; 2.1.3 HUM 2.1.4 可配置的操作特性 Outstanding transactions per TBU QoS 仲裁 2.2 Cache结构 2.2.1 Micro TLB 2.2.2 Macro…

交叉编译ethtool(ubuntu 2018)

参考文章&#xff1a;https://www.cnblogs.com/nazhen/p/16800427.html https://blog.csdn.net/weixin_43128044/article/details/137953913 1、下载相关安装包 //ethtool依赖libmul git clone http://git.netfilter.org/libmnl //ethtool源码 git clone http://git.kernel.or…

go语言Gin框架的学习路线(七)

GORM入门(基于七米老师) 目录 GORM入门 安装 连接数据库 连接MySQL 连接PostgreSQL 连接Sqlite3 连接SQL Server 我们搞一个连接MySQL的例子 创建数据库 GORM操作MySQL GORM是一个流行的Go语言ORM&#xff08;对象关系映射&#xff09;库&#xff0c;它提供了一种方…

Golang | Leetcode Golang题解之第273题整数转换英文表示

题目&#xff1a; 题解&#xff1a; var (singles []string{"", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine"}teens []string{&…

高效日志管理系统设计

设计一个高效的日志管理系统&#xff0c;旨在确保日志数据能够被有效收集、存储、分析和检索&#xff0c;同时也要考虑到系统的可扩展性、可靠性和易用性。以下是高效日志管理系统设计的关键要素&#xff1a; 1. 日志收集 自动收集&#xff1a;使用轻量级的日志采集代理&…

windows11 vmware安装记录

注意&#xff1a;windows11不要安装vmware16版本以下的&#xff01;&#xff01;&#xff01;会报错&#xff0c;与内核冲突&#xff0c;只有关闭内核才可以运动&#xff0c;但是这样电脑的安全性得不到保障。 Windows11 中 Vmware Workstations16 安装CentOS 7_windows featu…