C++ 2.0新特性——类型推导(auto、decltype)

C++ 2.0新特性——类型推导(auto、decltype)

一、类型推导

auto类型推导在大部分情况下就是模板类型推导,因此首先介绍模板类型的要点。

1、在模板类型推导中,具有引用类别的实参会被当成非引用类型来处理,即引用性会被忽略。(类型为指针或引用)

template<typename T>
void f(const T& param)

int x=10;
const int cx=x;
const int& rx=cx;

定义3个变量x,cx,rx分别作为函数f的参数,函数调用时,f(x)、f(cx)、f(rx),T都被推导为int,param都被推导为const int&。rx的引用性在推导时被忽略。

2、对万能引用(右值形参)形参进行推导时,左值实参会进行特殊处理,会区分实参是左值还是右值,而非万能引用不会。

template<typename T>
void f(T&& param) //param为万能引用

int x=10;
const int cx=x;
const int& rx=cx;

f(x):x是个左值,所以T类型为int&,param类型为int&
f(cx):cx是个左值,所以T类型为const int&,param类型为const int&
f(rx):rx是个左值,所以T类型为const int&,param类型为const int&
f(10):10是个右值,所以T类型为int,param类型为int&&

3、对按值传递(非指针和引用)的形参进行推导时,若实参类型中带有const或volatile修饰词时,会被当做不带const或volatile修饰词的类别来处理。

template<typename T>
void f(const T& param)

int x=10;
const int cx=x;
const int& rx=cx;

f(x)、f(cx)、f(rx)调用时,T和param的类型都被推导为int。

4、数组或函数类型的实参会退化为对应的指针,除非被用来初始化引用。

void someFunc(int,double);//函数,类型为void(int,double)

template<typename T>
void f1(T param);

template<typename T>
void f2(T& param);

f1(someFunc) :param被推导为函数指针,类型为void(*)(int,double)
f2(someFunc):param被推导为函数引用,类型为void(&)(int,double)

二、auto

1、在C++ 2.0引入auto时,与类型推导真正的区别在于:auto会假定用大括号括起来的初始化表达式代表一个initializer_list,但模版推导不会

auto x={1,2,3}; //x的类型为initializer_list<int>

template<typename T>
void f(T param);

f({1,2,3})调用时,编译无法通过,推导不出T的类型。
f(x)调用时,正常通过,T被推导为initializer_list。

2、在函数返回值或lambda表达式的形参中使用auto,意思是使用模板类型推导而非auto类型推导。

auto f()
{	
	return {1,2,3};//编译错误,无法完成类型推导
}

注:auto使用要点:
1、优先使用auto,而非显示类型声明。

*auto变量必须初始化,避免了未初始化的变量和啰嗦的变量声明。*

2、当auto推导的类型不符合要求时,使用显示类型声明强制auto推导出想要的类型(static_cast)。

*对于vector<bool> 的operator[]操作,auto的返回值并不是一个容器的引用,而是vector<bool>::reference类型的对象,做了一个bool的隐式转换*

三、decltype

1、绝大多数情况下,decltype会得出变量或表达式的类型而不作任何修改。

int i=0;  //decltype(i) 是int
const int i=0; //decltype(i) 是const int

2、对于类型为T的左值表达式,除非该表达式仅有一个名字,decltype总是推导出T&。

vector<int> v;//decltype(v) 是vector<int>
				//decltype(v[0])是int&
//容器的operator[] 返回类型取决于容器本身,一般都返回T&。

3、C++14支持decltype(auto),和auto一样,它会从其初始化表达式出发来推导类型,但是它的推导使用的是decltype的规则。

decltype(auto) f1()
{
	int x=0;
	return x;//decltype(x)为int,f1返回的是int
}

decltype(auto) f2()
{
	int x=0;
	return (x);//decltype((x))为int&,f1返回的是int&
}

f2返回的是一个局部变量的引用,因此会带来未定义行为的错误。

四、查看类型推导的结果

1、编译时,针对visual studio IDE,将鼠标悬停在某个变量、形参、函数等会显示对应的类别。
2、运行时,利用typeid(T).name也可以输出类型名。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dailingGuo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值