auto
C++11 中,使用 auto 关键字来进行自动类型推导。语法如下:
1 | auto name = value; |
其中,name 是变量的名字。value 是变量的初始值。其中 auto 是一个占位符,会在编译期间由编译器推导出来。而且由 auto 推导的变量必须初始化,因为是占位符的原因,不能用作声明。
限制:
- auto 不能在函数的参数中使用。
我们在定义函数的时候只是对参数进行了声明,指明了参数的类型,但并没有给它赋值,只有在实际调用函数的时候才会给参数赋值。而 auto 要求必须对变量进行初始化。
- auto 不能作用于类的非静态成员变量(即没有 static 关键字修饰的成员变量)中。
- auto 关键字不能定义数组,比如下面的例子就是错误的:
1 | char a[] = "abcdefg"; |
1 | error: ‘b’ declared as array of ‘auto’ |
- auto 不能作用于模板参数
1 | template <typename T> |
1 | error: invalid use of ‘auto’ |
decltype
decltype 是 C++11 新增的一个关键字,它和 auto 的功能一样,都用来在编译时期进行自动类型推导。
auto 和 decltype 关键字都可以自动推导出变量的类型,但它们的用法是有区别的:
1 | auto varname = value; |
其中,varname 表示变量名,value 表示赋给变量的值,exp 表示一个表达式。
auto 根据等号右边的初始值 value 推导出变量的类型,而 decltype 根据 exp 表达式推导出变量的类型,跟等号右边的 value 没有关系。
另外,auto 要求变量必须初始化,而 decltype 不要求。auto 是根据变量的初始值来推导出变量类型的,如果不初始化,变量的类型也就无法推导了。此外,我们必须要保证 exp 的结果是有类型的,不能是 void。例如,当 exp 调用一个返回值类型为 void 的函数时,exp 的结果也是 void 类型,此时就会导致编译错误。
1 | error: variable or field ‘b’ declared void |
注意:
- 如果 exp 是一个不被括号包围的表达式,或者是类成员访问表达式,或者是单独的变量,那么 decltype(exp) 的类型就和 exp 一致。
- 如果 exp 是函数调用,那么 decltype(exp) 的类型就和函数返回值的类型一致。
- 如果 exp 是一个左值,或者被括号包围,那么 decltype(exp) 的类型就是 exp 的引用。假设 exp 的类型为 T,那么 decltype(exp) 的类型就是 T&。
- decltype 如果是函数调用,因为是在编译时确定,和 sizeof 一样,不会调用一次函数。