1.auto
C++11中引入auto类型说明符,可以让编译器通过初值分析变量所属类型。故该类型变量必须在定义时初始化。
特点:
(1) 自动分析变量类型;
(2) 不可以和int、float等其他类型说明符一起使用;
(3) 会忽略掉顶层const属性,故可以与const修饰符一起使用;
(4) 定义多个变量,则初始值必须是同一类型。
注:顶层const指任意的对象本身是常量;而底层const则与指针和引用等复合类型的基本类型部分有关,指所指对象为常量(如指针常量中const为顶层const,而常量指针中的const为底层const)。
例:
const int i = 0, &r = i; //i为整形常量,r为i的引用
auto i1 = i; //i1是整形(忽略顶层const)
auto i2 = r; //i2是整形(r是i的别名,i本身是一个顶层const)
auto i3 = &i; //i3是指向整形常量的指针
auto &i4 = i; //i4是整形常量的引用
auto &i5 = 5; //错误! 不能为非常量引用绑定字面值
const auto &i6 = 5; //正确! 可以为常量引用绑定字面值
int t = 1;
auto &i6 = i, *t1 = &t; //错误! i类型为const int,而&t的类型为int,故auto无法统一表示
std::vector<std::string> vec;
std::vector<std::string>::iterator it1 = vs.begin();
auto it2 = vs.begin(); //显然用auto在代码简洁性上好得多
补充:对于模板函数,定义中使用auto作为变量类型也方便得多。
2.decltype(expression)
decltype是C++11中引入的类型说明符,用于查询表达式expression的类型。
2.1 特点
(1) decltype对顶层const和引用的处理方式与auto不同,返回expression的类型时,是附带expression原本的const与引用属性的;
int i = 0;
const int c = 1, &cr = c;
decltype(i) x1 = 0; //x1是int型
decltype(c) x2 = 0; //x2是const int型
decltype(cr) x3 = x2; //x3是const int&型
decltype(cr) x4; //错误! 因为x4和x3类型一样,是引用类型,必须初始化
(2) expression是表达式时,编译器只分析表达式的类型,但不计算它的值;
对于解引用(&)操作尤其要注意,解引用得到的是引用类型;
int i= 5, *p = &i, &r = i;
decltype(r + 0) b1; //b1是整型,因为表达式结果时整型
decltype(*p) b2; //错误! 解引用操作,得到的是int&类型,必须初始化
decltype(&p) b3; //b3是int**类型
(3) expression是函数,则返回值为函数返回值的类型;
float* func(){};
decltype(func) b4; //b4是float*类型
(4) expression是是带括号的变量,则返回值为引用类型;
int i= 0;
decltype(i) d1; //d1是int类型
decltype((i)) d2; //错误! d2是int&类型,必须初始化
decltype((i)) d3 = d1; //正确! d3是int&类型
注:
(1) auto在表示类型时不会附带等号右侧类型的 ‘ & ’、‘ * ’ 以及顶层const,而decltype会附带表达式的 ‘ & ’、‘ * ’ 以及顶层const;
(2)auto在遇到数组时,编译器会将其替换为一个指向数组首元素的指针,但是decltype不会;
int a[] = {1,2,3,4,5};
auto a1(a); //a1是一个整形指针,指向a的第一个元素;
decltype(a) a3 = {0,1,2,3,4,5,6,7,8,9}; // decltype(a)返回类型是含有十个整形元素的数组