C++模板参数类型推导分析一二

1. 模板函数参数类型推导

有三个关键点需要注意:

  1. 每个实参独立推导模板参数类型。
  2. 在每个实参的推导过程中,允许两种隐式转换,单向的非low-level const向low-level const转换(top-level const和精确匹配无异自不必说)和array和function向对应的指针类型的转换。
  3. 最终对同一个模板参数推导出的类型必须相同。

对于这三点的印证,可以看一下这个chatgpt的问答以供参考。
问题如下:

根据你掌握的C++标准相关的知识回答这个问题:

void func(T, T);
template<class T>
void func2(const T *, const T *);
int a, b;
int *pa = &a; const int *pb = &b;
func(pa, pb);
func2(pa, pb);

判断1: 对于func来说,推断参数T为const int *即可,这样pa隐式转换为const int *即可,只涉及low-level const conversion。
判断2: 对于func2来说,将T推断为int即可,这样pa隐式转换为const int *即可,只涉及low-level const conversion。
请分析两个判断是否正确

问答如下:

对 func 的调用

模板定义为:

template<class T>
void func(T, T);

调用时传入的参数类型分别为:

第一个参数:类型为 int*
第二个参数:类型为 const int*
模板参数 T 的推导过程要求两个参数必须推导出相同的 T。对第一个参数推导得到 T = int*;对第二个参数推导得到 T = const int*。由于 int* 与 const int* 不完全相同(指针指向的类型 cv 限定不同),模板参数推导不能通过将 T 统一为 const int* 来“补救”这一不匹配,因为模板参数推导过程中不考虑隐式转换(包括 low-level const 转换)。因此,调用 func(pa, pb) 会导致模板参数推导失败。

判断1中所述“对于 func 来说,推断参数 T 为 const int* 即可”是不正确的。

对 func2 的调用

模板定义为:

template<class T>
void func2(const T *, const T *);

调用时的参数仍然是:

第一个参数:类型为 int*
第二个参数:类型为 const int*
对第一个参数进行推导:要求参数类型 const T* 与 int* 匹配。推导时将指针解引用,得到要求 const T 与 int 匹配,此时 T 被推导为 int(推导过程中忽略了目标类型的 const 限定,因为它是 low-level 限定,需要在调用时通过隐式转换来补上)。
对第二个参数:要求 const T* 与 const int* 匹配,同样推导得到 T = int。

因此,两处均一致地推导出 T = int。推导完成后,函数参数类型为 const int*,对于第一个参数 int* 允许隐式转换为 const int*(low-level const 转换),对于第二个参数正好匹配。

判断2中所述“对于 func2 来说,将 T 推断为 int 即可”是正确的。

总结

判断1:错误。对于 func(pa, pb),模板参数 T 无法同时满足 int* 和 const int* 的要求,不能仅通过隐式转换统一为 const int*。
判断2:正确。对于 func2(pa, pb),T 被一致推导为 int,调用中 int* 隐式转换为 const int*,仅涉及 low-level const 转换。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

HilariousDog

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

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

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

打赏作者

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

抵扣说明:

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

余额充值