指针、常量和类型别名
如果某个类型别名指代的是复合类型或常量,那么把它用到声明语句里就会产生意想不到的后果。例如下面的声明语句用到了复合类型pstring,它实际上是类型char*的别名:
typedef char *pstring; // pstring是char*的别名
const pstring cstr = 0; // cstr是指向char的常量指针,类型是char *const cstr
const pstring *ps; // ps是一个指针,指向的对象类型是char *const cstr
auto类型说明符
使用auto也能在一条语句中声明多个变量。因为一条声明语句只有一个基本数据类型,所以该语句中所有变量的初始数据类型都必须一样:
auto i = 0, *p = &i; // 正确:i是整数、p是整形指针
auto sz = 0, pi = 3.14; // 错误:sz和pi的类型不一致
复合类型、常量和auto
当引用被当作auto声明语句的初始值时,真正参与初始化的其实是引用对象值。此时编译器以引用对象的类型作为auto的类型:
int i = 0, &r = i;
auto a = r; // a是一个整数
其次,auto一般会忽略掉顶层const,但底层const会保留下来:
const int ci = i, &cr = ci;
auto b = ci; // b是整数,非const
auto c = cr; // C是整数,非const
auto d = &i; // d是整型指针(i是一个整型变量)
auto e = &ci; // e是一个指向整数常量的指针,类型const int*
如果希望推出的auto类型是一个顶层const,需要明确指出:
const auto f = ci; // ci是int类型,f是const int类型
还可以将引用的类型设置为auto,此时原来的初始化规则仍然适用:
auto &g = ci; // g是整型常量引用,const int&
auto &h = 42; // 错误,非常量引用不能绑定到字面值
const auto &j = 42; // 正确
符号&和*只从属于某个声明符,而非基本数据类型的一部分,因此初始值必须是同一类型:
auto k = ci, &l = i; // 正确,k是整数,l是整型引用
auto &m = ci, *p = &ci; // 正确,m是const int&,p是const int*
auto &n = i, *p2 = &ci; // 错误,n是int&,p2是const int*