auto和decltype类型推导

1. auto关键字推导
auto关键字的推导与木板参数推导规则一致。两个可以做简单类比,如


template<typename T> 
void f(T);

f(1)
auto  a = 1 //该处类型推导过程与f中形参类型的推导规则一致,引用类型可类比

参考Modern C++中的描述,类型推导过程可以分为三类:

  1. 非引用类型
    非引用类型推导时,右侧赋值参数或表达式的引用或cv标记直接丢弃,然后做类型推导,如:
// 返回值为右值
int dummy(){ return 0; }
// ar为引用类型
int a = 0; int& ar = a;
// ca为常量
const int ca = 0;

// 三种类型的变量赋值,推导的类型
auto d1 = dummy()   // auto为int
auto d2 = ar;       // auto为int
auto d3 = ca;       // auto为int

  1. 引用类型

1)左值引用
对上述三种的推导结果如下:

// 返回值为右值
int dummy(){ return 0; }
// ar为引用类型
int a = 0; int& ar = a;
// ca为常量
const int ca = 0;

// 三种类型的变量赋值,推导的类型
auto& d1 = dummy()   // 编译报错,左值引用仅能与左值关联
auto& d2 = ar;       // auto为int
auto& d3 = ca;       // auto为 const int

ca常量赋值给引用时,auto推导为const int。转化为模板函数推导更容易理解。template <typename T> f(T& t),调用者在调用该接口调用时,若传入为常量,显然在接口内也是不希望被修改的,所以T推导为const int更为合理,即引用类型下cv修饰符是可以保留的。对比1中的非引用类型,如果想要通过auto定义引用类型的变量,需要写为auto&,因为对引用类型推导中会丢弃引用符号,const修饰符类似。同时非引用类型和引用类型的auto类型推导,也有模板类型推导时的退化问题,这种退化主要体现在数组和函数指针的推导中。
2) 右值引用
对上述三种的推导结果如下:

// 返回值为右值
int dummy(){ return 0; }
// ar为引用类型
int a = 0; int& ar = a;
// ca为常量
const int ca = 0;

// 三种类型的变量赋值,推导的类型
auto&& d1 = dummy()   // auto 为int类型
auto&& d2 = ar;       // auto为int&
auto&& d3 = ca;       // auto为const int&

最后两个的推导比较特殊,普遍引用在类型推到时遵循&折叠规则,所以在右侧表达市为左值时,auto为引用类型,并且cv修饰符保留。
auto关键字在变量声明上有一种非常有意思的写法;

auto a = 1, &b = a; 

2. decltype关键字推导
decltype多用于对表达的的类型推导,多用于模板定义中不知道表达式具体类型时。典型用例如下:

template<typename T>
auto add(T a, T b)->decltype(a+b) //返回值类型未知,故显示说明返回值类型
{
	return a+b; 
}

对上述几种类型的推导结果如下

// 返回值为右值
int dummy(){ return 0; }
// ar为引用类型
int a = 0; int& ar = a;
// ca为常量
const int ca = 0;

// decltype(dummy()) 为int&&
// decltype(ar) 为int&
// decltype(ca) 为const int

// decl对表达式的推导结果与运算符的常规定义相同,如[]返回为引用类型,所以:
// int a[10] = {} 中decltype(a[0])为int&,因为a[0]是可赋值的引用类型。

通过上述推导结果可以看到decltype可以获取到表达式的真实类型,不会做decay处理。

2. decltype(auto)关键字推导
decltype(auto)是C++14中引入的类型推导方式,借助它可以省去类型模板函数中对返回值的显式说明。

int a = 1, b = 2;
decltype(auto) = a + b; //其推导过程等价为decltype(a+b) c = a + b
发布了18 篇原创文章 · 获赞 3 · 访问量 9874

猜你喜欢

转载自blog.csdn.net/u011388696/article/details/90548934