笔记1。模板类型推导

博客介绍了C++模板推导的三种情况。一是形参为引用或指针,实参为引用时引用会被忽略,指针情况类似;二是形参为通用引用,传入右值时推导为右值引用,传入左值时推导为左值引用;三是形参非指针和引用,推导时忽略引用、const、volatile修饰。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

分三种情况:

1.形参类型是引用(左值引用和右值引用,而不是通用引用(Universal Reference))或者指针。

(1)当实参是引用时,引用会被忽略。然后根据实参和形参推导出T类型。

template <typename T>
void f( T& param ){} //T&是个左值引用

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

f(x);//x是int,结合形参可以推出T为int,形参最终为int&
f(cx); //cx是const int,推出T为const int,形参最终为const int&
f(rx); //rx是const int&, 引用会被忽略,当成const int看待,结果同上
//把上面模板改成:
template <typename T>
void f( const T& param ){} //多了个const

f(x);//x是int,结合形参可以推出T为int,形参最终为const int&
f(cx); //cx是const int,推出T为 int,形参最终为const int&
f(rx); //rx是const int&, 引用会被忽略,当成const int看待,结果同上

(2)对应指针的情况也类似:

template <typename T>
void f(  T* param );//T*是个指针


int x;
int *cx = &x;
const int *cpx = &x;
int * const pcx = &x;
int * const *pp = &cx;

f(cx);//T被推导为int,最终形参为int*
f(cpx); //T被推导为const int,最终形参为const int*
f(pcx); /*非书上例子,T被推导为int,最终形参为int*,
             *至于这里const为什么被抛弃,我感觉是这种情况推不出完全符合的情况
             *(把T推导成const int,这样明显是错误的推导)*/
f(pp); //非书上例子,T被推导为int *const,最终形参为int *const*,
           

(3)右值引用与左值引用也一样(个人的理解,书中没给出例子)。

template <typename T>
void f( T&& param )//实际上是个通用引用(模板参数&&),但传入右值的时候行为与上面提到的左值引用一致
{
}

int x = 5;
const int && rr = 7;


f(5); //T推导为int, 形参最终为 int&&
f(rr);//rr是右值引用,但是它本身是个左值,相当于传入了左值(传入左值的情况下面会讨论到)
f(std::move(rr));//T推导为const int,形参最终为 const int&&

2.形参为通用引用(如果函数模板中的一个模板参数为T,那么形参T&&就是个通用引用(长得像右值引用,分场合区分))

(1)当传入实参是右值的时候,跟上面提到的右值情况一样,T&&最终会被推导为相应的右值引用。

(2)当传入实参是左值的时候,形参最终被推导为相应的左值引用。

template <typename T>
void f( T&& param )//通用引用(模板参数&&)
{
}

 int x = 27;
 const int cx = x;
 const int& rx = x;
 int array[] = {1,2,3};

 f(x); //T推导为int&, 形参为int&&&,根据引用折叠,最终为int&
 f(cx);//T推导为const int&, 形参为const int&&&,根据引用折叠,最终为const int&
 f(rx);//T推导为const int&, 形参为const int&&&,根据引用折叠,最终为const int&
 f(array);//数组引用传递的时候(对应函数引用传递也一样)不会退化为指针,所以T推导为int (&)[3],形参最终为int (&)[3]

3.当形参不是指针和引用

(1)这看起来是传值,所以意味着复制的含义。那么推导的时候会忽略引用,const、volatile修饰。

template <typename T>
void f( T param )
{
}

 int x = 27;
 const int cx = x;
 const int& rx = x;
 int array[] = {1,2,3};
 const int arr[] = {1,2,3};
 int const * const p = &x;

 f(x); //T推导为int,形参最终为int
 f(cx);//T推导为int,形参最终为int
 f(rx);//T推导为int,形参最终为int
 f(array);//array退化为int*,T推导为int*,形参最终为int*
 f(arr);//array退化为const int*,T推导为const int*,形参最终为const int*(const修饰的不是arr,而是里面的元素,所以这const不会被舍弃)
 f(p);//第二个const是修饰p的,所以被省略,最终T推导为int const*(const int*),形参与T相同

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值