- decltype用于编译时类型推导,是以一个普通表达式作为参数,返回该表达式的类型,而且decltype并不会对表达式进行求值。
- decltype的用法:
1 //推导出表达式类型 2int i = 4; 3decltype(i) a;//首先推导变量i的类型为int,然后通过返回结果声明变量a,a的类型为int
- 在C++中,我们有时候会遇上一些匿名类型,如:
-
1struct2{ 3int d; 4double b; 5}anon_s;
而借助decltype,我们可以重新使用这个匿名的结构体:
-
1decltype(anon_s) as;//定义了一个上面匿名的结构体
- decltype推导四规则:
- 如果e是一个没有带括号的标记符表达式或者类成员访问表达式,那么decltype(e)就是e所命名的实体的类型(注意:如果e是一个被重载的函数,则会导致编译错误)
- 否则,假设e的类型是T,如果e是一个将亡值,那么decltype(e)为T&&
- 否则,假设e的类型为T,如果e是一个左值,那么decltype(e)为T&
- 否则,假设e的类型为T,则decltype(e)为T
- 举例说明:
-
1 int i = 4; 2 int arr[5] = {0}; 3 int *ptr = arr; 4 struct s 5 { 6 double d; 7 }s; 8 void Overloaded(int); 9 void Overloaded(char);//函数重载 10 int && RvalRef(); 11 const bool Func(int); 12 13 //规则1,推导为其类型 14 decltype (arr) var1;//没有括号的标记符表达式,为其实体类型int 15 decltype(ptr) var2;//没有括号的标记符表达式,为其实体类型int * 16 decltype(s.d) var3;//没有括号的类成员访问表达式,为其实体类型double 17 decltype(Overloaded) var4;//重载函数,编译错误 18 19 //规则2,将亡值,推导为类型的右值引用 20 decltype (RvalRef()) var5 = 1; 21 22 //规则3,左值,推导为类型的引用 23 decltype ((i)) var6 = i; //int & 24 decltype (true ? i:i) var7 =i;//int & 25 decltype (++i) var8 =i; //int & 26 decltype (arr[5]) var9 =i;//int & 27 decltype (*ptr) var10 = i; 28 decltype ("hello") var11 = "hello";//const char(&) [9],字符串字面常量为左值,且为const左值 29 30 //规则4:以上都是不,则推导为本类型 31 decltype (1) var12; //const int 32 decltype (Func(1)) var 13 = true;//const bool 33 decltype(i++) var14 = i;//int i++返回右值
- 注意:字符串字面值常量为左值,而且是const左值,而非字符串字面常量则是右值