类型别名
1,传统方法是使用typedef关键字
typedef int a; //此时a相当于int
typedef a base, *p; //此时base相当于a,p相当于int*
2,新的方法,使用别名声明
using aa = int; //此时aa相等于int
注:真正使用时,类型别名的理解不能替换为原来的样子
eg:
typedef char * paseing;
const char *a; //此时数据类型为char,*变成了声明符的一部分
const paseing b=0; //数据类型就是指针int c = 10;
b = &c; //此时b不可变
*b = c; //*b可以重新指向对象
第二行是声明了一个指向const char的指针,第三行则是指向char的常量指针。
auto类型说明符
用编译器替我们去分析表达式所属的类型,是通过初始值来推算变量的类型,所以auto定义的变量必须有初始值
同时auto也能在一条语句中声明多个变量,但是改语句中所有变量的初始基本数据类型都必须一样
auto a = 0, *b = &a; //此时a是int类型,b是整形指针
auto aa = 0, bb = 1.11; //错误aa和bb的数据类型不一样
注:
- auto一般会忽略掉顶层const,而底层const则会保留下来,如果需要是一个顶层const,则需要明确指出
const int a = 10; int aa = 20;
auto b = a; b = 20; //顶层const被忽略
auto c = &aa; //c是一个整型指针(整数的地址就是指向整数的指针)
c = &aa; //c是指针auto d = &a; //d是一个指向整数常量的指针(对常量对象取地址是一种底层const)
d = 20; //d是常量
- 设置一个初始值为auto的引用时,初始值中的顶层属性依然保留
const int a = 10;
auto &b = a; //b是一个整型常量引用
auto &c = 10; //不能为非常量引用绑定字面值
const auto &d = 10; //可以为常量引用绑定字面值
decltype类型说明符
编译器分析表达式并得到它的类型,却不实际计算表达式的值
- decltype处理顶层const和引用的方式与const不同,如果decltype使用的表达式是一个变量,则decltype返回该变量的类型
const int a = 0, &b = a;
decltype(a) c = 0; //c的类型是const int
decltype(b) d = c; //d的类型是const int &,d必须绑定到变量
decltype和引用
int a = 10, *b = &a, &c = a;
decltype (a + 0) aa; //正确,加法的结果时int,因此aa时是int类型;显然这个表达式的结果将是一个具体的值并非是一个引用
decltype(*b) bb; //错误,bb是int&类型,必须初始化;解引用指针可以得到指针所指的对象,还能给这个对象赋值,因此结果类型是int &。
如果表达式是一个引用,则结果是引用类型
如果表达式是解引用操作,则将得到引用类型
注:如果decltype使用的是一个不加括号的变量,则得到的结果就是该变量的类型,如果再加上一层扩号,则编译机器就把他看作是一个表达式,此时结果永远是引用。
int a;
decltype (a) aa; //正确,扩号的的结果是int,因此aa时是int类型
decltype((a)) aaa; //错误,aaa是int&类型,必须初始化