Type Declarations
auto
C++11 使用 auto
来自动类型推断,这要求显示初始化,让编译器能够将变量设置为初始值的类型。auto
的推导规则如下:
-
auto 基本规则:去掉引用和 const 资格。
-
保持引用和常量性:使用 auto&、const auto&、auto* 等。
-
数组和指针:数组会被推导为指针
在 auto 的推导中,如果表达式本身包含自动推导的类型(如 std::vector
decltype
基本规则
- 对标识符或类成员访问表达式:
decltype(x)
的类型与 x
的类型相同。如果 x
是变量,则 decltype(x)
的类型是该变量的类型。与 auto
不同的 decltype
会保留 cv 限定符和引用属性。
- 对左值表达式:
如果 expr
是一个左值表达式,则 decltype(expr)
是 T&
,其中 T
是 expr
的类型。
- 对右值右值表达式:
如果 expr
是一个右值表达式,则 decltype(expr)
是 T
,其中 T
是 expr
的类型。
下面我们使用一种特殊的手段验证上述推导规则。使用一种不定义模板函数的方式,让编译器推导完类型后找不到实现报错,从而看到具体的推导类型:
#include <iostream>
#include <vector>
template<class Tp>
void f();
int main() {
int a = 5;
const int& b = a;
auto c = b; // c 是 int,auto 去掉了引用和 const
decltype(b) d = a; // d 是 const int&,decltype 保留了引用和 const
std::vector<int> v;
decltype(v[0]) e = a; // e 是 int&,因为 v[0] 返回一个左值引用
decltype((a)) f = a; // f 是 int&,因为 (a) 是一个左值表达式
decltype(a) g = a; // g 是 int,直接使用标识符 a,decltype(a) 是 int
return 0;
}
- 对于标识符或类成员,
decltype
获取其声明类型。 - 对于左值表达式,
decltype
会生成一个引用类型。 - 对于右值表达式,
decltype
会生成其值类型。
返回值类型后置
C++11 引入了返回值类型后置(trailing return type),这种语法通过在参数列表之后使用 ->
指定返回类型,提供了一些便利和优势。具体好处如下:
- 当返回类型依赖于函数参数时,返回值类型后置可以更方便地表示:
- lambda 表达式引入了后置返回类型的语法,使得匿名函数能够使用复杂的返回类型: