auto 和 decltype均是c++11提出的。
一. auto
auto让编译器通过初始值来推断变量的类型,故auto定义的变量必须有初始值。
如:
auto sz = 0, pi = 3.14; //错误,推断出的类型不一致
(1)auto与引用
①引用其实是使用引用的对象,特别是用作初始化时。
如:
int i=0, &r = i; auto a = r; // a是一个整形
②auto一般忽略顶层const,同时底层const则会保留下来。
如:
const int ci = i, &cr = ci; auto b = ci; // b是整形 auto c = cr; // c是整形,结合①。 auto d = &i; // d是整形指针 auto e = &ci; // e是指向整形常量的指针(对常量对象取地址是底层const)
③想推断出的auto 是一个顶层const。
如:
const auto f = ci; //f是const int类型
④还可以将引用的类型设为auto,原来规则仍然适用.
如:
auto &g = ci; //g是整形常量引用 auto &h = 42; // 错误:不能为非常量引用指定字面值 const auto &k = 42; // 正确
设置一个类型为auto 的引用时,初始值的顶层const仍然保留。
二. decltype
针对auto,不想用表达式初始化变量则可用decltype。
decltype处理顶层const和引用的方式和auto些许不同。
(1)decltype与const
如:
const int ci = 0, &cr = ci; decltype(ci) x = 0; // x是const int decltype(cr) y = x; // y 是const int &
引用从来都作为其所指对象的同义词出现,只有用在decltype处是个例外。
(2)decltype与 引用
①
如:
decltype(cr + 0) b; // 加法结果是Int, 故b的类型是int(未初始化) int *p = 0; decltype(*p) c; // c是int &,必须初始化
②decltype和auto另一重要区别,decltype的结果类型与表达式形式密切相关。
如果给变量加上了一层或者多层括号,编译器会把它当成一个表达式;变量是一种可以作为赋值语句左值的特殊表达式,所以decltype会得到引用类型。
如:
decltype((i)) d; // 错误:这里的d是int & decltype(i) d; //d是int(未初始化)
联系:
①指针和数组(函数指针同样)
int a[] = {0,1,2,3}; auto ap(a); // ap是int * decltype(a) ap; // ap是一个数组(ap是常量)
auto会将数组转换成指针,decltype则不会。
②函数
auto func() -> int (*)[4]; 等价于: int arr[] = {0,1,2,3}; decltype(arr) *func();
对于返回函数指针用法同上。