模版实参推断和引用

本文详细介绍了C++中模版参数推断的过程,特别是关于引用类型的情况,包括左值引用和右值引用的绑定规则,以及引用折叠规则。

模版参数推断包含函数指针及引用等部分,此处只介绍有关引用的模版参数推断。

考虑下面的例子:

template<typename T> void f(T &p);

其中函数参数p是一个模版类型参数T的引用,记住以下两点:

i、编译器会应用正常的引用绑定规则;

ii、const是底层的,不是顶层的。

1、从左值引用函数参数推断类型

当一个函数参数是模版类型参数的一个普通(左值)引用时(即,形如T&),绑定规则:只能传递给它一个左值(如,一个变量或一个返回引用类型的表达式)。实参可以是const类型,也可以不是。如果实参是const的,则T将被推断为const类型。

举例如下:

template<typename T> void f1(T&);//实参必须是一个左值
//对f1的调用使用实参所引用的类型作为模版参数类型
f1(i);//i是一个int;模版参数类型T是一个int
f1(ci);//ci是一个const int;模版参数T是const int
f1(5);//错误:传递给一个&参数的实参必须是一个左值

当一个函数参数的类型是const T&,正常的绑定规则:可以传递给它任何类型的实参——一个对象(const或非const)、一个临时对象或是一个字面常量值。

举例如下:

template<typename T> void f2(const T&);//实参可以是一个左值,也可以是一个右值
//对f1的调用使用实参所引用的类型作为模版参数类型
f2(i);//i是一个int;模版参数类型T是一个int
f2(ci);//ci是一个const int;模版参数T是int
f2(5);//一个const &参数可以绑定到一个右值;T是int

2、从右值引用函数参数推断类型

当一个函数参数是一个右值引用(即,形如T&&)时,正常绑定规则:可以传递给它一个右值。当传递右值时,类型推断过程类似普通左值引用函数参数的推断过程。

举例如下:

template<typename T> void f3(T&&);
f3(42);//实参是一个int类型的右值;模版参数T是int

3、规则例外:引用折叠和右值引用参数

个人总结:除遵循上述两条规则外,主要是&的折叠及右值引用的推断,其根据结果为导向推断T的实际类型,遵守的规则如下:

记X为给定类型,

i、X& &、X& &&和X&& &都折叠成类型X& 

ii、X&& &&折叠成X&&(给右值引用传递右值时,最后的的类型为X&&)(仅此折叠生成右值引用)

第3点例外规则导致如下几个重要结果:

a、如果一个函数参数是一个指向模板类型参数的右值引用(如,T&&),则它可以被绑定到一个左值;且(见b)

b、(接a)如果实参是一个左值,则推断出的模版实参类型将是一个左值引用,且函数参数将被实例化为一个(普通)左值引用参数(T&)

c、可以将任意类型的实参传递给T&&类型的函数参数。

举例如下:

template<typename T> void f3(T&&);
f3(i);//实参是一个左值;模版参数T是int&
f3(ci);//实参是一个左值;模版参数T是一个const int&
f3(42);//实参是一个右值;模版参数T是一个int

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值