- 类型别名
在C++11之前,如果定义类型别名使用 typedef 方式来定义,定义的方式如下:
//typedef 类型名 别名
typedef double Salary;
typedef double *Base; //Base是double* 类型
这种定义方式有点类似与定义一个变量的方式,只是定义的标示符不是变量名而是类型名
这种定义方式有一个缺点,当在定义如指针等复合类型,特别是加入const标示符之后,使得定义变得难于理解,如:
typedef char *pstring;
const pstring cstr = 0; // cstr是一个自身是const类型的指针,指针指向的类型是char类型的变量
const pstring *ps; // ps 是一个指针的指针,它指向const类型的指针,这个const类型的指针指向的类型是char类型的变量
- auto关键字
auto关键字用于类型的推导,可以简化我们去写大段的类型定义(特别是容器中的迭代器),auto使用中需要初始化才能进行推导,如:
int val1=0, val2=1;
auto item = val1+val2; // item是int类型
std::vector<std::string> svec;
for(std::vector<std::string>::iterator iter = svec.begin(); iter != svec.end(); ++iter)
可以简写为
for(auto iter = svec.begin(); ...)
使用auto时,当推导复合类型以及const修饰符的时候需要注意:
1. 当在引用中推导时,auto代表该引用实际绑定对象的类型,如:
int i = 0;
int &r = i;
auto a = r; //a是int类型,因为r绑定的类型是int
2. auto在推导中会忽略顶层const(Top-level const),但是底层const(Low-level const)会被保留
int i = 0;
const int ci = i, &cr = ci;
auto b = ci; // b是int类型 (顶层const被忽略)
auto c = cr; // c 是int类型
auto d = &i; // d是int*类型
auto e = &ci; // e 是const int*类型(&ci得到的类型是指向const int类型的指针,是底层const)
如果我们想保留顶层的const,那么我们需要显示地声明,如:
const int ci = 10;
const auto f = ci; // f是const int类型
由于引用不是对象,因此引用中的const都是Low-level const,在auto推导类型的时候会被保留:
const int ci = 10;
auto &g = ci; // g 是const int&类型
- decltype关键字
有时候我们不需要用一个表达式来初始化一个变量,而只是想知道这个表达式最终得到的是什么类型的变量,这时候我们可以使用decltype关键字:
decltypde推导类型与auto有一些不同:
1. decltype会保留顶层的const
2.decltype会保留引用
const int ci = 0, &cj = ci;
decltype(ci) x = 0; // x 是const int类型(Top-level const得到保留)
decltype(cj) y = x; // y 是const int& 类型
另外关于decltype还需要注意的地方:
当decltype((变量名))这时候得到的是一个引用的类型,但是decltype(变量名)只有当变量类型是引用类型的时候,才得到引用的类型.
如:
int i = 1;
decltypde((i)) d; //d是int& 类型
decltypde(i) e; //e是int类型