类型推导之decltype

来源:互联网 发布:女性情趣用品 知乎 编辑:程序博客网 时间:2024/05/16 03:57
decltype关键字
跟auto一样,也是用来实现类型推导,但是auto只能根据变量的初始化表达式来推导,即必须初始化。
decltype也是在编译时推导,不会实际计算表达式的值,类似于一元运算符sizeof

如:

decltype (func()) sum = x;//sum的类型为函数func的返回值的类型,这里并不调用函数func




推导规则:
1、如果对decltype使用的表达式是一个不加括号的变量,或者是一个类成员变量访问表达式,则推导出的类型为表达式一致,且保留CV限定与引用
如:
volatile const int& x = 0;decltype (x) a ;//a -> const volatile int&  同时,由于没有对引用进行初始化,此句错误int *p = &x;decltype (p)* pp = &p;//pp -> int **class Foo{public:static const int NUmber = 0;int x;}decltype (Foo::NUmber) c = 0;//c -> const intFoo foo;decltype (foo.x) d = 0;//d -> intint h = 0;decltype (h) i = 0;//i -> int


2、如果对decltype使用的表达式是函数调用,推导出的类型和返回值一致,如果函数返回的是一个临时变量,推导类型为右值引用,如果函数是重载函数,编译器将报错
如:
decltype (Foo()) j = 0;//j -> Foo&&构造函数返回了临时变量int&& fun();decltype (fun()) K = 0;//k -> int&&int func();decltype (func()) sum = x;//sum -> int普通函数调用const int func_cint ();decltype (func_cint()) l = 0;//l -> int函数返回值为右值const Foo func_cfoo();decltype (func_cfoo()) m = Foo;//m -> const Foo返回值为类类型的右值可以带CV限定符


3、如果对decltype使用的表达式结果是左值,推导出的类型为左值引用,表达式结果是右值,则推导出的类型为右值的类型
如:
//此段代码摘自:http://www.cnblogs.com/QG-whz/p/4952980.htmlint i = 4;int arr[5] = { 0 };int *ptr = arr;  decltype (true ? i : i) var7 = i; //int&  条件表达式返回左值。 decltype (++i) var8 = i; //int&  ++i返回i的左值。 decltype (arr[5]) var9 = i;//int&. []操作返回左值 decltype (*ptr)var10 = i;//int& *操作返回左值 decltype ("hello")var11 = "hello"; //const char(&)[9]  字符串字面常量为左值,且为const左值。decltype (1) var12;//const intdecltype (i++) var14 = i;//int i++返回右值int n = 0, p = 0;decltype (n + p) q;//q ->intdecltype (n += p) r;//r ->int&


4、如果对decltype使用的表达式被括号括起来了,类型推导的结果永远是左值引用
如:
int y = 0;decltype ((y)) z;//z -> int&同时,由于没有对引用进行初始化,此句错误


5、C++ primer上的一个情况
inti = 42, &r = i;decltype (r + 0) b;//b -> int

解释:因为r是一个引用,因此decltype (r)的结果为引用类型,如果想让结果类型时r所指的类型,可以把r作为表达式的一部分,如r + 0,显然这个表达式的结果将是一个具体的值而非一个引用

应用
1.推导出表达式类型
2.与using/typedef合用,用于定义类型。
3.重用匿名类型
4.泛型编程中结合auto,用于追踪函数的返回值类型

参考
C++11特性:decltype关键字 http://www.cnblogs.com/QG-whz/p/4952980.html
C++ Primer
深入应用C++ 11
0 0