【C++ 11】auto 自动类型推导

news2024/11/22 16:45:12

文章目录

  • 【 1. 基本用法 】
  • 【 2. auto 的 应用 】
    • 2.0 auto 的限制
    • 2.1 简单实例
    • 2.2 auto 与指针、引用、const
    • 2.4 auto 定义迭代器
    • 2.5 auto 用于泛型编程

  • 问题背景
    在 C++11 之前的版本(C++98 和 C++ 03)中,定义变量或者声明变量之前都必须指明它的类型,比如 int、char 等;但是在一些比较灵活的语言中,比如 C#、JavaScript、PHP、Python 等,程序员在定义变量时可以不指明具体的类型,而是让编译器(或者解释器)自己去推导,这就让代码的编写更加方便。C++11 为了顺应这种趋势开始使用 auto 关键字支持自动类型推导。
  • auto 的前身
    在之前的 C++ 版本中,auto 关键字用来指明变量的存储类型,它和 static 关键字是相对的:auto 表示变量是自动存储的,这也是编译器的默认规则,所以写不写都一样,一般我们也不写,这使得 auto 关键字的存在变得非常鸡肋。

【 1. 基本用法 】

  • C++11 赋予 auto 关键字新的含义,使用它来做自动类型推导。C++ 中的变量必须是有明确类型的,使用了 auto 关键字以后,编译器会在编译期间自动推导出变量的类型,然后用真正的类型代替 auto 这个占位符 ,这样我们就不用手动指明变量的数据类型了。使用 auto 类型推导的变量必须马上初始化,以方便编译器进行类型判断。
  • 基本语法
    • var_name 是变量的名字。
    • value 是变量的初始值。
auto var_name = value;

【 2. auto 的 应用 】

2.0 auto 的限制

auto的 限制案例描述
使用 auto 的时候必须对变量进行初始化内部机制,为了编译器能够依据初始化值进行类型判断。
auto 不能在函数的参数中使用。这个应该很容易理解,我们在定义函数的时候只是对参数进行了声明,指明了参数的类型,但并没有给它赋值,只有在实际调用函数的时候才会给参数赋值;而 auto 要求必须对变量进行初始化,所以这是矛盾的。
auto 不能作用于类的非静态成员变量 (也就是没有 static 关键字修饰的成员变量)中。/
auto 不能定义数组如下代码错误,arr 为数组,所以不能使用 auto:
char url[] = “http://c.biancheng.net/”;
auto str[] = url;
auto 不能作用于模板参数如下代码错误,auto 不能作用于模板参数:
template class A{
    //TODO:
};
int main(){
    A<int> C1;
    A<auto> C2 = C1; //错误
    return 0;
}

2.1 简单实例

  • 实例1
    第 1 行中,10 是一个整数,默认是 int 类型,所以推导出变量 n 的类型是 int。
    第 2 行中,12.8 是一个小数,默认是 double 类型,所以推导出变量 f 的类型是 double。
    第 3 行中,由双引号""包围起来的字符串是 const char* 类型,所以推导出变量 url 的类型是 const char*,也即一个常量指针。
auto n = 10;
auto f = 12.8;
auto url = "Hello,My friend!";
  • 实例2:连续定义多个变量
    第一个子表达式,&n 的类型是 int*,编译器会根据 auto *p 推导出 auto 为 int。后面的 m 变量自然也为 int 类型,所以把 99 赋值给它也是正确的。
    推导的时候不能有二义性 :在本例中,编译器根据第一个子表达式已经推导出 auto 为 int 类型,那么后面的 m 也只能是 int 类型,如果写作m=12.5就是错误的,因为 12.5 是double 类型,这和 int 是冲突的。
int n = 20;
auto *p = &n, m = 99;

2.2 auto 与指针、引用、const

  • 先给出小结:
    在这里插入图片描述

  • 实例1
    第 2 行代码中,p1 为 int * 类型,也即 auto * 为 int *,所以 auto 被推导成了 int 类型。
    第 3 行代码中,auto 被推导为 int* 类型,前边的例子也已经演示过了。
    第 4 行代码中,r1 为 int & 类型,auto 被推导为 int 类型。
    第 5 行代码是需要重点说明的,r1 本来是 int& 类型,但是 auto 被推导为 int 类型,这表明 当等号 “=” 右边的表达式是一个引用类型时,auto 会把引用抛弃,直接推导出它的原始类型

int  x = 0;
auto *p1 = &x;  //p1 为 int *,auto 推导为 int
auto  p2 = &x;  //p2 为 int*,auto 推导为 int*
auto &r1 = x;   //r1 为 int&,auto 推导为 int
auto r2 = r1;   //r2 为  int,auto 推导为 int
  • 实例2
    第 2 行代码中,n 为 const int,auto 被推导为 int。
    第 3 行代码中,n 为 const int 类型,但是 auto 却被推导为 int 类型,这说明 当等号 “=” 右边的表达式带有 const 属性时( 不是 引用+const 类型), auto 不会使用 const 属性,而是直接推导出 non-const 类型
    第 4 行代码中,auto 被推导为 int 类型,这个很容易理解,不再赘述。
    第 5 行代码中,r1 是 const int & 类型,auto 也被推导为 const int 类型,这说明 当等号 “=” 右边的表达式带有 const 和引用 & 时,auto 的推导将保留表达式的 const 类型
int  x = 0;
const auto n = x;  //n 为 const int ,auto 被推导为 int
auto f = n;      //f 为 const int,auto 被推导为 int(const 属性被抛弃)
const auto &r1 = x;  //r1 为 const int& 类型,auto 被推导为 int
auto &r2 = r1;  //r1 为 const int& 类型,auto 被推导为 const int 类型

2.4 auto 定义迭代器

  • auto 的一个典型应用场景是用来 定义 STL 的迭代器
  • 问题背景
    我们在使用 stl 容器的时候,需要使用迭代器来遍历容器里面的元素;不同容器的迭代器有不同的类型,在定义迭代器时必须指明,而迭代器的类型有时候比较复杂,书写起来很麻烦,如下所示:定义迭代器 i 的时候,类型书写比较冗长,容易出错。
#include <vector>
using namespace std;
int main(){
    vector< vector<int> > v;
    vector< vector<int> >::iterator i = v.begin();
    return 0;
}
  • 然而有了 auto 类型推导,我们大可不必这样,只写一个 auto 即可。修改上面的代码,使之变得更加简洁:
    auto 可以根据表达式 v.begin() 的类型(begin() 函数的返回值类型)来推导出变量 i 的类型。
#include <vector>
using namespace std;
int main(){
    vector< vector<int> > v;
    auto i = v.begin();  //使用 auto 代替具体的类型
    return 0;
}

2.5 auto 用于泛型编程

  • auto 的另一个应用就是当我们不知道变量是什么类型,或者不希望指明具体类型的时候,比如泛型编程中。
  • 实例
    本例中模板函数 func() 会调用所有类的静态函数 get(),并对它的返回值做统一处理,但是 get() 的返回值类型并不一样,而且不能自动转换。这种要求在以前的 C++ 版本中实现起来非常的麻烦,需要额外增加一个模板参数,并在调用时手动给该模板参数赋值,用以指明变量 val 的类型:
#include <iostream>
using namespace std;
class A {
public:
    static int get(void) {
        return 100;
    }
};
class B {
public:
    static const char* get(void) {
        return "Hello,My friend!";
    }
};
template <typename T1, typename T2>  //额外增加一个模板参数 T2
void func(void) {
    T2 val = T1::get();
    cout << val << endl;
}
int main(void) {
    //调用时也要手动给模板参数赋值
    func<A, int>();
    func<B, const char*>();
    return 0;
}
  • 但是有了 auto 类型自动推导,编译器就根据 get() 的返回值自己推导出 val 变量的类型,就不用再增加一个模板参数了,如下所示:
#include <iostream>
using namespace std;
class A {
public:
    static int get(void) {
        return 100;
    }
};
class B {
public:
    static const char* get(void) {
        return "Hello,My friend!";
    }
};

template <typename T>
void func(void) {
    auto val = T::get();
    cout << val << endl;
}
int main(void) {
    func<A>();
    func<B>();
    return 0;
}

在这里插入图片描述

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

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

相关文章

目标检测YOLO实战应用案例100讲-【目标检测】YOLOV11

目录 前言 算法原理 YOLO发展历程 什么是 YOLO11 YOLOv11 的主要特点 YOLO各版本概览 核心优势: YOLOv11改进方向 YOLOv11功能介绍 YOLOv11关键创新 YOLOv11 指标展示 YOLOV11实验 环境设置 准备数据集 训练模型 验证模型 应用领域 一、智慧交通与自动驾…

【Linux实践】实验八:Shell程序的创建及变量

文章目录 实验八&#xff1a;Shell程序的创建及变量实验目的&#xff1a;实验内容&#xff1a;操作步骤&#xff1a;1. 查看环境变量2. 定义变量AK3. 定义变量AM并比较4. 创建Shell程序 实验八&#xff1a;Shell程序的创建及变量 实验目的&#xff1a; 掌握Shell程序的创建过…

【C++】AVL树的底层以及实现

个人主页 文章目录 ⭐一、AVL树的概念&#x1f389;二、AVL树的性质&#x1f3dd;️三、AVL树的实现1. 树的基本结构2. 树的插入3. 树的旋转• 左单旋• 右单旋• 左右双旋• 右左双旋 &#x1f3a1;四、AVL树的其它功能1. 树的查找2. 树的遍历3. 树的高度4. 树的大小 &#x…

RK3568平台开发系列讲解(I2C篇)i2c 总线驱动介绍

🚀返回专栏总目录 文章目录 一、i2c 总线定义二、i2c 总线注册三、i2c 设备和 i2c 驱动匹配规则沉淀、分享、成长,让自己和他人都能有所收获!😄 i2c 总线驱动由芯片厂商提供,如果我们使用 ST 官方提供的 Linux 内核, i2c 总线驱动已经保存在内核中,并且默认情况下已经…

vulnhub-matrix-breakout-2-morpheus靶机的测试报告

目录 一、测试环境 1、系统环境 2、使用工具/软件 二、测试目的 三、操作过程 1、信息搜集 2、Getshell ①nc反弹shell连接 ②Webshell上传 3、提权 ①使用kali自带的poc ②使用msf进行渗透 四、结论 一、测试环境 1、系统环境 渗透机&#xff1a;kali2021.1(19…

项目构建工具

一般面试中被问到的项目构建工具&#xff0c;常常会回答的是Maven 今天大概了解了一下目前项目构建构建有Maven,Ant,Gradle Gradle 是一个构建工具&#xff0c;它是用来帮助我们构建app的&#xff0c;构建包括编译&#xff0c;打包等过程。我们可以为Gradle指定构建规则&…

matlab 相关

1、xcorr 本质上是两个函数做内积运算 相关算法有两种&#xff1a; 在Matlab上既可以 1.用自带的xcorr函数计算互相关&#xff0c;2.通过在频域上乘以共轭复频谱来计算互相关&#xff1b; 网友验证程序 clc;clear;close all; % s1,s2为样例数据 s1 [-0.00430297851562500;-…

攻防世界----->Replace

前言&#xff1a;做题笔记。 下载 查壳。 upx32脱壳。 32ida打开。 先运行看看&#xff1a; 没有任何反应&#xff1f; 猜测又是 地址随机化(ASLR)---遇见过。 操作参考&#xff1a; 攻防世界----&#xff1e;Windows_Reverse1_dsvduyierqxvyjrthdfrtfregreg-CSDN博客 然后…

Spring系列 Bean创建过程

文章目录 初始化时机单例初始化流程getBeandoGetBeangetSingleton(String) 获取单例getSingleton(String, ObjectFactory) 创建单例beforeSingletonCreationcreateBeanafterSingletonCreation 创建 Bean 过程doCreateBeanaddSingletonFactory createBeanInstance 创建 Bean 对象…

医院管理智能化:Spring Boot技术革新

3系统分析 3.1可行性分析 通过对本医院管理系统实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本医院管理系统采用JAVA作为开发语言&#xff0c;Spring Boot框…

ctf.bugku - game1

题目来源&#xff1a; game1 - Bugku CTF 访问页面&#xff0c;让玩游戏 得到100分&#xff0c;没拿到flag 查看页面源码&#xff0c; GET请求带有 score、IP、sign 三个参数&#xff0c;最后的flag 应该跟分数有关&#xff1b; 给了score一个99999分数&#xff0c; sign 为 …

STM32编码器接口

一、概述 1、Encoder Interface 编码器接口概念 编码器接口可接收增量&#xff08;正交&#xff09;编码器的信号&#xff0c;根据编码器旋转产生的正交信号脉冲&#xff0c;自动控制CNT自增或自减&#xff0c;从而指示编码器的位置、旋转方向和旋转速度每个高级定时器和通用…

如何录制微课教程?K12教育相关课程录制录屏软件推荐

在当今数字化教育的时代&#xff0c;微课作为一种重要的教学资源&#xff0c;受到了越来越多教师和学生的关注。制作一节优质的微课&#xff0c;录制是关键的环节之一。下面我们将结合相关知识&#xff0c;详细介绍如何录制微课教程。 一、微课录制前的准备 1.教学设计文档编写…

Ultralytics:YOLO11使用教程

Ultralytics&#xff1a;YOLO11使用教程 前言相关介绍前提条件实验环境安装环境项目地址LinuxWindows YOLO11使用教程进行目标检测进行实例分割进行姿势估计进行旋转框检测进行图像分类 参考文献 前言 由于本人水平有限&#xff0c;难免出现错漏&#xff0c;敬请批评改正。更多…

题目:圆桌会议

解题思路&#xff1a; 结果的顺序就是原序列的逆序&#xff0c;例如12345就是54321为结果顺序。同时将一个顺序序列&#xff08;非环&#xff09;变成逆序需要的次数为。想要的得到最短的交换次数&#xff0c;只需要将环尽量对半分&#xff0c;然后分别对两部分进行顺序序列变逆…

DAY27||回溯算法基础 | 77.组合| 216.组合总和Ⅲ | 17.电话号码的字母组合

回溯算法基础知识 一种效率不高的暴力搜索法。本质是穷举。有些问题能穷举出来就不错了。 回溯算法解决的问题有&#xff1a; 组合问题&#xff1a;N个数里面按一定规则找出k个数的集合切割问题&#xff1a;一个字符串按一定规则有几种切割方式子集问题&#xff1a;一个N个数…

SeaTunnel如何创建Socket数据同步作业?

本文为Apache SeaTunnel Socket Connector的使用文档&#xff0c;旨在帮助用户快速理解和有效利用Socket Connector&#xff0c;助力用户的应用程序实现高效、稳定的网络通信。 Socket是应用层与TCP/IP协议族之间进行通信的中间软件抽象层&#xff0c;它是网络编程的基础&…

视频怎么做成扫码展示?视频二维码在线做的方法

视频想要快速的分享给其他人&#xff0c;选择生成二维码是一种很方便的形式&#xff0c;其他人只需要扫描二维码就可以在线查看视频&#xff0c;与其他分享方式相比更加的简单、方便。现在日常生活中有很多场景都会有视频二维码的应用&#xff0c;简化了获取视频的流程&#xf…

typora笔记导出word格式:

Pandoc&#xff1a;各系统下载github链接 https://github.com/jgm/pandoc/releases/latest windows安装包 链接&#xff1a;https://pan.baidu.com/s/17AZNIMImbzFtWJAcAfAB0g?pwd55l2 提取码&#xff1a;55l2 先解压压缩包 点击 设置Pandoc路径&#xff0c;然后选择pa…

处理器中的几种hazard

什么是hazard? Instructions interact with each other in pipeline ; Structural Hazard 原因&#xff1a; An instruction in the pipeline may need a resource being used by another instruction in the pipeline ;Structural hazard occurs when two instructions nee…