处理类型
类型别名
类型别名是一个名字,是某种类型的同义词。类型别名可以使得复杂类型的名字变得简单明了、易于理解和使用。定义类型别名的两种方式:
// 使用关键字typedef:
typedef double wages; // wages是double的同义词
typedef wages base, *p; // base是double的同义词,p是double * 的同义词
wages hourly, weekly; // 等价于 double hourly, weekly;
// 使用别名声明:using name = type;
using time = int; // time 是 int 的同义词
time month, year; // 等价于 int month, year;
需要注意类型别名指代复合类型或常量的情况:
typedef char *pstring; // pstring的基本类型是一个指针
const pstring cstr = 0; // cstr 是一个常量指针,指向char类型
// 等价于 char *const cstr;
auto类型说明符(C++11)
auto
可以让编译器通过变量的初始值来推算变量的类型。因此auto定义的变量必须有初始值,且在一条语句中声明多个变量时,所有变量的初始基本数据类型必须都一样。
auto item = val1 + val2; // item 初始化为val1和val2相加的结果
auto i = 0, *p = &ival; // 正确,i 是整数, p 是整型指针
auto sz = 0, pi = 3.14; // 错误:sz是整数, pi是浮点数
需要注意auto和复合类型及常量的情况:
int ival = 0, &iRef = &ival;
auto a = r; // a是一个int对象
// 参与初始化的其实是被引用的对象ival
const int ci = ival, &cRef = &ci;
auto b = ci; // ci的顶层cosnt被忽略,b是一个int对象
auto c = cRef; // cRef是ci的别名,cRef的顶层const被忽略
auto d = &ival; // d是整型指针类型
auto e = &ci; // e是一个指向整型常量的指针
// 对常量对象取地址是一种底层const
可以将引用类型设置为auto
auto &g = ci; // g是整型常量引用,绑定在ci上
decltype类型指示符(C++11)
decltype
可以让编译器分析表达式得到类型,却不计算表达式的值。
decltype(f()) sum = x; // sum的类型就是函数f()的返回类型
不同于auto,如果decltype使用的表达式是一个变量,则decltype返回该变量的类型(包括顶层const和引用在内):
const int ci = 0, &cj = ci;
decltype(ci) x = 0; // x的类型是const int,必须被初始化
decltype(cj) y = x; // y的类型是const int&, 绑定到变量x上
// 下面操作将引发错误
// error: 'j' declared as reference but not initialized
decltype(cj) z;
如果decltype使用的表达式不是一个变量,则decltype返回表达式结果对应的类型。如果表达式的内容是解引用操作,则decltype将得到引用类型。decltype的结果类型与表达式形式密切相关。
int i = 42, *p = &i, &r = i;
decltype(r + 0) b; // 加法的结果是int,b是一个int对象
decltype(*p) c = i; // c是一个Int&,必须被初始化
需要注意的是, decltype((variable))
(这里是双层括号)的结果永远是引用,而decltype(variable)
的结果只有当variable本身就是一个引用时才是引用。
int i2 = 42;
decltype((i2)) d = i; // d是int&,必须被初始化
decltype(i) e =; // e是一个int对象