decltype与auto关键字一样,用于进行编译时类型推导,不过它与auto还是有一些区别的。decltype的类型推导并不是像auto一样是从变量声明的初始化表达式获得变量的类型,而是总是以一个普通表达式作为参数,返回该表达式的类型,而且decltype并不会对表达式进行求值。
decltype的推导规则可以简单概述如下:
如果exp是一个不被括号()包围的表达式,或者是一个类成员访问表达式,或者是一个单独的变量,decltype(exp)的类型和exp一致
如果exp是函数调用,则decltype(exp)的类型就和函数返回值的类型一致
如果exp是一个左值,或被括号()包围,decltype(exp)的类型就是exp的引用,假设exp的类型为T,则decltype(exp)的类型为T&
- struct A {
- double x;
- };
-
- const A* a = new A{0};
第一种情况
- decltype(a->x) y; // type of y is double
- decltype((a->x)) z = y; // type of z is const double&,因为a一个常量对象指针
第二种情况
- int* aa=new int;
- decltype(*aa) y=*aa; //type of y is int&,解引用操作
第三种情况
- decltype(5) y; //type of y is int
- decltype((5)) y; //type of y is int
- const int&& RvalRef() { return 1; }
- decltype ((RvalRef())) var = 1; //type of var is const int&&
与using/typedef合用,用于定义类型。
- using size_t = decltype(sizeof(0));//sizeof(a)的返回值为size_t类型
- using ptrdiff_t = decltype((int*)0 - (int*)0);
- using nullptr_t = decltype(nullptr);
-
- vector<int>vec;
- typedef decltype(vec.begin()) vectype;
- for (vectype i = vec.begin; i != vec.end(); i++){...}
显而易见,与auto一样,也提高了代码的可读性。
重用匿名类型。在 C++ 中,我们有时候会遇上一些匿名类型。
- struct {
- int d ;
- double b;
- } anon_s;
借助 decltype,我们可以重新使用这个匿名的结构体,C++11 之前我们是无法做到的。
decltype(anon_s) as; //定义了一个上面匿名的结构体
注意,匿名类型有其匿名的原因,一般情况下,匿名类型不应该被重用,应尽量避免这种用法。
泛型编程中结合 auto,用于追踪函数的返回值类型,这是 decltype的最大用途。decltype 帮助 C++ 模板更加泛化,程序员在编写代码时无需关心任何时段的类型选择,编译器会合理地进行推导。
- template <typename _Tx, typename _Ty> auto multiply(_Tx x, _Ty y)->decltype(x*y) {
- return x*y;
- }
【C++】C++11新增关键字详解_郭老二的博客-CSDN博客_c++11关键字