auto类型说明符辨析
1、简要说明:
c++11引入了auto类型说明符,用它可以让编译器替我们去分析表达式所属的类型。与只对应一种特定类型的说明符(double,int....)不同的是,auto是通过初始值来推算变量的类型。这也说明了auto定义的变量必须要初始化。
auto i = 3; //这里i会被定义为int型 auto j = 3.23; //这里i会被定义为double型 auto k = i + j; //由于初始化表达式运算的结果是double型这里k也是double型 //由上面的例子可以得出 auto item = v1 + v2 //item的类型是由v1和v2相加的结果推断出的
2、auto一条语句中声明多个变量的情况:
auto i = 1, j = 2; //正确,因为j和i根据表达式的推到结果都是int型 auto a = 1, b = 2.2; //错误,编译器在分析时发现i是int型,b是浮点型,由于auto只能表示一种基本类型则这里就会报错
编译器报错信息如下(测试编译器为微软的CL编译器):
test-code1:
#include<iostream> using namespace std; int main() { auto i = 3; //这里i会被定义为整型 auto j = 3.23; //这里i会被定义为浮点型 auto k = i + j; //由于初始化表达式运算的结果是浮点型这里k也是浮点型 // auto a = 1, b = 2.2; //error auto c = 1, d = 2; //查看i,j,k类型的字节大小 cout << "i:" << sizeof(i) << " " << "j:" << sizeof(j) << " " << "k:" << sizeof(k) << " " << "c:" << c << "--sizeof:"<< sizeof(c) << " " << "d:" << d << "--sizeof:"<< sizeof(d) << endl; return 0; }
Debug---outcome:
这里:
sizeof(double) = 8byte
sizeof(int)= 4byte
3、auto的初始化为复合类型的情况:
- 当初始值为整型的引用类型 :
int i = 1; int &r = i; auto a = r; //这里r为int型,而不是引用类型(在判断时我们就关注r表示的是什么,很明显r其实就是i的一个代号。。。)
- auto一般会忽略顶层的const,同时底层的const则会保留下来:
- 顶层const与底层const的简析:(详细分析点击此处:暂未完成)
const int i = 1; const int *p = &i; //这里p是指向整型常量的指针:*p是不可变的,但P本身是可变的>>>这是底层const int j = 1; int *const p2 = &j; //这里p2是指向整型的常量指针:*p是可变的,但p本身不可变>>>>>>这是顶层const const int *const p3 = &i;//这里p3是指向整型常量的常量指针:*p和p本身都不可变>>>p3即使顶层const也是底层const
- 用顶(底)层const初始化auto变量:
int *r = p2; //正确,p2的顶层const可以忽略 int *r1 = p1; //错误,p1有底层const属性 auto *r2 = p2; //r2会被认为是int*型 auto *r3 = p1; //r3--------是const int auto *r4 = p3; //r4--------是const int(顶层const被忽略了)
- auto如何保留初始表达式的顶层const:用户自己指定auto类型变量的const
//情况1,i(不可变)是有顶层的const,会被auto忽略,f会被认为是int.加左边的const后f变成顶层const const auto f = i; //const int i = 1; auto *const r5 = p3; //情况2,保存指针的顶层const
- 图像分析const顶层与底层(指针p):本身不可变<const>是顶层,指向的不可变<const>这是这个本身变量的底层
- 顶层const与底层const的简析:(详细分析点击此处:暂未完成)
test-code2:
#include<iostream> using namespace std; int main() { const int i = 1; const int *p1 = &i; //这里p是指向整型常量的指针:*p是不可变的,但P本身是可变的>>>这是底层const *p1 = 2; //错误 int k = 2; p1 = &k; //正确 /*-----------------------------分割线1----------------------------------*/ int j = 1; int *const p2 = &j; //这里p2是指向整型的常量指针:*p是可变的,但p本身不可变>>>>>>这是顶层const *p2 = 4; //正确 p2 = &i; //错误 /*-----------------------------分割线2------------------------------- --*/ const int *const p3 = &i;//这里p3是指向整型常量的常量指针:*p和p本身都不可变>>>p3即使顶层const也是底层const int *r = p2; //正确,p2的顶层const可以忽略 int *r1 = p1; //错误,p1有底层const属性 /*-----------------------------分割线3------------------------------- --*/ auto *r2 = p2; //r2会被认为是int*型 auto *r3 = p1; //r3--------是const int auto *r4 = p3; //r4--------是const int(顶层const被忽略了) /*-----------------------------分割线4------------------------------- --*/ //情况1,i(不可变)是有顶层的const,会被auto忽略,f会被认为是int.加左边的const后f变成顶层const const auto f = i; auto *const r5 = p3; //情况2,保存指针的顶层const return 0; }