title | date | tags | categories | description | |||||
---|---|---|---|---|---|---|---|---|---|
C++处理类型
|
2020-04-27 06:43:54 -0700
|
|
|
|
类型别名
typedef
typedef double wages; //wages是double的同义词
typedef wages base, *p; //base是double的同义词,p是double*的同义词
含有typedef
的语句定义的不是变量而是类型别名
using
新标准规定了一种新的方法,使用别名声明
using size = std::string::size_type;
这种方法使用using
作为别名声明的开始,其后紧跟别名和等号,其作用是把左侧的名字规定成等号右侧类型的别名。
指针,常量和类型别名
typedef char *pstring;
const char *cstr1 = 0;
const pstring cstr2 = 0;
再上例中,人们可能会误以为cstr1和cstr2是等价的,实际上,这两种定义截然不同,cstr1的const
是底层的,即值为常量,而cstr2为顶层const
,即指针为常量,后者相当于
char *const cstr2 = 0;
auto类型说明符
C++11新标准引入了auto
类型说明符,用它就能让编译器替我们分析表达式所属的类型,auto
让编译器通过初始值来推算变量类型,因此auto
定义的变量必须有初始值
auto num = func(); //假设func()返回float,则num类型就是float
使用auto
也能在一条语句中声明多个变量,该语句中所有变量的初始基本数据类型必须一致
auto i = 0, *p = &i; //正确,i是整数,p是整数指针
auto sz = 0, pi = 3.14; //错误,类型不一致
复合类型,常量和auto
编译器推断出来的auto
类型有时候和初始值的类型不完全一样,编译器会适当的改变结果使其更符合初始化规则
- 引用 当引用备用作初始值时,真正参与初始化的其实是引用对象的值,此时编译器以引用对象的类型作为
auto
的类型
int i = 0, &r = i;
auto a = r; //a为int类型
对于a的定义相当于
int a = r;
而不是
int &a = r;
- const
auto
一般忽略顶层const,保留底层const
const int ci = i, &cr = ci;
auto b = ci; //b是int类型(忽略了顶层const)
auto c = cr; //c是int类型(cr是ci引用,ci本身是顶层const)
auto d = &i; //d是一个int*类型
auto e = &ci; //e是指向const int的指针(对常量取地址是一种底层const)
如果希望auto
是顶层const,可以明确指出
const auto f = ci;
还可以将引用的类型设为auto
auto &g = ci;
auto &h = 42; //错误,不能将非常量引用绑定到字面值
const auto &j = 42; //正确
- 数组 当使用一个数组作为
auto
变量的初始值时,推断得到的类型是指针而不是数组
int ia[] = { 0, 1, 2, 3, 4 }
auto ia2(ia); //ia2是一个指针,指向ia的第一个元素
decltype类型指示符
C++11新标准引入,它的作用是选择并返回操作数的数据类型,在此过程中,编译器分析表达式并得到其类型,却不实际计算表达式的值
decltype(f()) sum = x; //sum类型就是函数f的返回类型
注意,这里并不实际调用f(),而只是识别其返回类型
- 对比auto
decltype
处理类型和auto
有些不同,如果decltype
使用的表达式是一个变量,则返回包括顶层const和引用在内的该变量的类型。
const int ci = 0, &cj = ci;
decltype(ci) x = 0; //x类型是const int
decltype(cj) y = x; //y类型是const int&,绑定到x
decltype(cj) z; //错误,z是一个引用,必须初始化
- decltype和引用 如果
decltype
使用的表达式不是一个变量而是表达式,则返回表达式结果对应的类型
int i = 42, *p = &i, &r = i;
decltype(r + 0) b; //正确,加法的结果是int,因此b类型为int
decltype(*p) c; //错误,c是一个引用,必须初始化
如decltype(*p)
所示的那样,如果表达式的内容是解引用操作,则decltype
将得到引用类型,正如我们熟悉的那样,*p
解引用可以得到对象的值,并可以给对象赋值,所以decltype
得到的是int&
而不是int
decltype
和表达式形式密切相关,如果给变量名加上了一对或多对括号,编译器就把它当成了表达式,这样的decltype
会得到引用类型
decltype((i)) d; //错误,d是int&,必须初始化
decltype(i) e; //正确,e是int
切记:
decltype((variable))
结果永远是引用,而decltype(variable)
只有当variable
本身是引用时才是引用
- 数组 当使用
decltype
且初始值为一个数组时,不会发生auto
那样的转化
int ia[] = { 0, 1, 2, 3, 4 }
decltype(ia) ia2 = { 5, 6, 7, 8, 9 }; //ia2是一个含有5个元素的数组