首页 > 其他分享 >auto 类型

auto 类型

时间:2023-09-09 22:11:36浏览次数:24  
标签:const 变量 推导 int auto 类型

auto类型说明符
1、C++11标准引入了auto类型说明符,用它能让编译器主动去分析表达式所属的类型。

2、auto定义变量必须有初始值,编译器通过初始值来推算变量的类型。

3、可以在一条语句中用auto声明多个变量,但要求该语句中所有变量的初始值的基本数据类型都必须一样。(注意*和&并非基本数据类型的一部分)

例如:

auto i=0, *p=&i; //正确:i是整数,p是整型指针
auto sz=0, pi=3.14; //错误:sz和pi的类型不一致
1
2
4、当表达式是一个引用类型时,编译器以引用对象的类型作为auto的类型。

5、auto一般会忽略顶层const,保留底层const。

6、如果希望保留顶层const,需要明确指出。

7、设置一个类型为auto的引用时,原来的初始化规则仍然适用,且初始值中的顶层const属性仍然保留。

例如:

int i=0, &r=i;
const int ci=i, &cr=ci;
auto a=r; //(第4条)a是一个整数(int)
auto b=ci; //(第5条)b是一个整数(int)
auto c=cr; //(第4、5条)c是一个整数(int)
auto d=&i; //(第5条)d是一个整型指针(int*)
auto e=&ci; //(第5条)e是一个指向整型常量的指针(const int*)
const auto f=ci; //(第6条)f是指向整型常量的常量指针(const int* const)
auto &g=ci; //(第7条 保留底层const属性)g是一个整型常量引用,绑定到ci
auto &h=42; //(第7条 初始化规则)错误:不能为非常量引用绑定字面值
const auto &j=42; //(第6条、第7条 初始化规则)正确:可以为常量引用绑定字面值

 

 

1. auto 的应用场景
auto 在实际开发中到底有什么应用呢?下面我们列举两个典型的应用场景。

1.1 使用 auto 定义迭代器
auto 的一个典型应用场景是用来定义 stl 的迭代器。

我们在使用 stl 容器的时候,需要使用迭代器来遍历容器里面的元素;不同容器的迭代器有不同的类型,在定义迭代器时必须指明。而迭代器的类型有时候比较复杂,书写起来很麻烦,请看下面的例子:

#include <vector>
using namespace std;
int main(){
vector< vector<int> > v;
vector< vector<int> >::iterator i = v.begin();
return 0;
}
1
2
3
4
5
6
7
可以看出来,定义迭代器 i 的时候,类型书写比较冗长,容易出错。然而有了 auto 类型推导,我们大可不必这样,只写一个 auto 即可。

修改上面的代码,使之变得更加简洁:

#include <vector>
using namespace std;
int main(){
vector< vector<int> > v;
auto i = v.begin(); //使用 auto 代替具体的类型
return 0;
}
1
2
3
4
5
6
7
auto 可以根据表达式 v.begin() 的类型(begin() 函数的返回值类型)来推导出变量 i 的类型。

1.2 auto 用于泛型编程
auto 的另一个应用就是当我们不知道变量是什么类型,或者不希望指明具体类型的时候,比如泛型编程中。我们接着看例子:

#include <iostream>
using namespace std;
class A{
public:
static int get(void){
return 100;
}
};
class B{
public:
static const char* get(void){
return "http://c.biancheng.net/cplus/";
}
};
template <typename T>
void func(void){
auto val = T::get();
cout << val << endl;
}
int main(void){
func<A>();
func<B>();
return 0;
}


运行结果:
100
http://c.biancheng.net/cplus/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
本例中的模板函数 func() 会调用所有类的静态函数 get(),并对它的返回值做统一处理,但是 get() 的返回值类型并不一样,而且不能自动转换。这种要求在以前的 C++ 版本中实现起来非常的麻烦,需要额外增加一个模板参数,并在调用时手动给该模板参数赋值,用以指明变量 val 的类型。

但是有了 auto 类型自动推导,编译器就根据 get() 的返回值自己推导出 val 变量的类型,就不用再增加一个模板参数了。

下面的代码演示了不使用 auto 的解决办法:

#include <iostream>
using namespace std;
class A{
public:
static int get(void){
return 100;
}
};
class B{
public:
static const char* get(void){
return "http://c.biancheng.net/cplus/";
}
};
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;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2. auto 类型推导的语法和规则
在之前的 C++ 版本中,auto 关键字用来指明变量的存储类型,它和 static 关键字是相对的。auto 表示变量是自动存储的,这也是编译器的默认规则,所以写不写都一样,一般我们也不写,这使得 auto 关键字的存在变得非常鸡肋。

C++11 赋予 auto 关键字新的含义,使用它来做自动类型推导。也就是说,使用了 auto 关键字以后,编译器会在编译期间自动推导出变量的类型,这样我们就不用手动指明变量的数据类型了。

auto 关键字基本的使用语法如下:
auto name = value;

name 是变量的名字,value 是变量的初始值。

注意:auto 仅仅是一个占位符,在编译器期间它会被真正的类型所替代。或者说,C++ 中的变量必须是有明确类型的,只是这个类型是由编译器自己推导出来的。

auto 类型推导的简单例子:

auto n = 10;
auto f = 12.8;
auto p = &n;
auto url = "http://c.biancheng.net/cplus/";
1
2
3
4
下面我们来解释一下:
第 1 行中,10 是一个整数,默认是 int 类型,所以推导出变量 n 的类型是 int。
第 2 行中,12.8 是一个小数,默认是 double 类型,所以推导出变量 f 的类型是 double。
第 3 行中,&n 的结果是一个 int* 类型的指针,所以推导出变量 p 的类型是 int*。
第 4 行中,由双引号""包围起来的字符串是 const char* 类型,所以推导出变量 url 的类型是 const char*,也即一个常量指针。

我们也可以连续定义多个变量:

int n = 20;
auto *p = &n, m = 99;
1
2
先看前面的第一个子表达式,&n 的类型是 int*,编译器会根据 auto *p 推导出 auto 为 int。后面的 m 变量自然也为 int 类型,所以把 99 赋值给它也是正确的。

这里我们要注意,推导的时候不能有二义性。在本例中,编译器根据第一个子表达式已经推导出 auto 为 int 类型,那么后面的 m 也只能是 int 类型,如果写作m=12.5就是错误的,因为 12.5 是double 类型,这和 int 是冲突的。

还有一个值得注意的地方是:使用 auto 类型推导的变量必须马上初始化,这个很容易理解,因为 auto 在 C++11 中只是“占位符”,并非如 int 一样的真正的类型声明。

3.auto 的用法
auto 除了可以独立使用,还可以和某些具体类型混合使用,这样 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
1
2
3
4
5
下面我们来解释一下:
第 2 行代码中,p1 为 int* 类型,也即 auto * 为 int ,所以 auto 被推导成了 int 类型。
第 3 行代码中,auto 被推导为 int 类型,前边的例子也已经演示过了。
第 4 行代码中,r1 为 int & 类型,auto 被推导为 int 类型。
第 5 行代码是需要重点说明的,r1 本来是 int& 类型,但是 auto 却被推导为 int 类型,这表明当=右边的表达式是一个引用类型时,auto 会把引用抛弃,直接推导出它的原始类型。

接下来,我们再来看一下 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 类型
1
2
3
4
5
下面我们来解释一下:
第 2 行代码中,n 为 const int,auto 被推导为 int。
第 3 行代码中,n 为 const int 类型,但是 auto 却被推导为 int 类型,这说明当=右边的表达式带有 const 属性时, auto 不会使用 const 属性,而是直接推导出 non-const 类型。
第 4 行代码中,auto 被推导为 int 类型,这个很容易理解,不再赘述。
第 5 行代码中,r1 是 const int & 类型,auto 也被推导为 const int 类型,这说明当 const 和引用结合时,auto 的推导将保留表达式的 const 类型。

最后我们来简单总结一下 auto 与 const 结合的用法:
当类型不为引用时,auto 的推导结果将不保留表达式的 const 属性;
当类型为引用时,auto 的推导结果将保留表达式的 const 属性。

4. auto 的限制
前面介绍推导规则的时候我们说过,使用 auto 的时候必须对变量进行初始化,这是 auto 的限制之一。那么,除此以外,auto 还有哪些其它的限制呢?

auto 不能在函数的参数中使用。
这个应该很容易理解,我们在定义函数的时候只是对参数进行了声明,指明了参数的类型,但并没有给它赋值,只有在实际调用函数的时候才会给参数赋值;而 auto 要求必须对变量进行初始化,所以这是矛盾的。

auto 不能作用于类的非静态成员变量(也就是没有 static 关键字修饰的成员变量)中。

auto 关键字不能定义数组,比如下面的例子就是错误的:
char url[] = “http://c.biancheng.net/”;
auto str[] = url; //arr 为数组,所以不能使用 auto

auto 不能作用于模板参数,请看下面的例子:

template <typename T>
class A{
//TODO:
};
int main(){
A<int> C1;
A<auto> C2 = C1; //错误
return 0;
}

标签:const,变量,推导,int,auto,类型
From: https://www.cnblogs.com/jacy1234/p/17690266.html

相关文章

  • C语言:数据类型之整形(一)
     什么是数据?记录一天各个时间的温度,那么这个温度就是数据.记录一个水库水位的变化值,那么这个值就是数据.什么是数据类型?1215是整数12.23是小数"helloworld"是一段话基本数据类型:数值类型:整形,浮点型。整形顾名思义就是整数,像:1,2,3,4,5就是整形整形在C语言的关键字是:int......
  • Go类型全解:常量与变量大全!
    本篇文章深入探讨了Go语言中类型确定值、类型不确定值以及对应类型转换的知识点,后续充分解析了常量与变量及其高级用法,并举出丰富的案例。关注公众号【TechLeadCloud】,分享互联网架构、云服务技术的全维度知识。作者拥有10+年互联网服务架构、AI产品研发经验、团队管理经验,......
  • 教你快速上手C语言中的数据类型和变量
    (章节目录)前言  哈喽,各位铁汁们好啊!✨今天来给大家带来的是初识C语言里面的数据类型和变量。  今天主要带大家简单认识-一下C语言,俗话说没吃过猪肉,也见过猪跑。了解下每个数据类型是干嘛的。可以读懂C语言的简单程序,其他的博主就不多介绍了。  后面会为大家详细介绍......
  • 17、复合类型之引用(P45、P46)
     P45倒数第五行“引用为对象起了另外一个名字,引用类型引用另外一种类型。”intx=10;//声明一个整数变量x,并初始化为10int&refX=x;//声明一个整数引用refX,它是x的别名ref就是x的另外一个名字,refX就是引用类型,它引用了x(int整形)P45倒数第四行,声明符:具体来说,声......
  • Java基础——基本数据类型转换
    基本数据类型转换基本数据类型数据类型所占字节取值范围boolean未定false与truebyte1个字节-2^7~2^7-1char2个字节0~2^16-1short2个字节-2^15~2^15-1int4个字节-2^31~2^31-1long8个字节-2^63~2^63-1float4个字节-2^128~+2^128double8个字节-2^1024~+2^1024方法调用规则从低位类型到......
  • Java注解支持的类型
    我们经常会自定义注解,自定义注解时,可能会需要定义各种数据类型,但是自定义注解可以包含哪些数据类型,是存在限制的。主要有如下几种:Aprimitivetype:基本类型(java的八种基本类型:byte、short、int、long、float、double、char、boolean)String:字符串Class:Class......
  • AutoCAD Electrical下载-AutoCAD Electrical中文版下载 功能介绍
    AutoCADElectrical2020是一款面向电气设计师们使用的cad软件,在CAD原有的基础上添加了创建原理图,导线编号,生成物料清单等用于自动完成电气控制工程设计任务的工具,是电气行业用户专用的cad软件型号。软件地址:看置顶贴AutoCADElectrical2013中文安装教程:1、AutoCADElectrical20......
  • Autocad Electrical 2020中文电气版64位下载 新功能介绍
    本文为电气控制设计师准备了2022版AutoCADElectrical,此软件延续了AutoCAD一贯的用户界面,上手非常容易,可以有效提升电气设计效率。这一版本的软件优化了功能按钮和布局,而且还可以将标题栏位置和对正属性保留到非活动图形中。软件地址:看置顶贴性能引见1、提升出产效力工程师在开启电......
  • python进阶 day08字典数据类型内置方法
    字典数据类型内置方法1.作用对于值添加描述信息使用他2.定义方式用{}以逗号隔开加入键值对:key:valueinfo_dict={'name':'wangdapao','age':18,'height':120,'gender':'female','hobby_list':['dapao','basketball'......
  • 元组数据类型内置方法
    元组数据类型内置方法元组和列表的内置方法一模一样,但是元祖无法修改元组咋i定义的那一刻他的元素个数以及元素的值就全部固定了毫无用处,早期永远一般用于减小内存占用,以后只要定义列表就行了定义方式列表的中括号改成小括号tup=(1,2,3,4,5)内置方法查看索引位置......