函数模板与函数重载

本文主要总结一下涉及到函数模板的函数重载,其中的一些知识点。

函数重载

什么样的 同名(signatrue) 函数构成函数重载?

  1. 不同参数个数
  2. 不同参数类型
  3. 不同参数顺序
  4. 类成员函数的 constnon-const
  5. 指针和引用的 constnon-const
  6. 函数模板(特化)与普通函数。
f(int)
f(const int)           // error
f(int &)
f(int const&)
template<typename T> void f(T a)
template<> void f<int>(int a)

重载解析

对于一个命名函数的调用,通常会使用下列的处理方法:

  1. 确定同名的函数,组成重载(候选)集;
  2. 模板实参演绎;
  3. 函数匹配,选择最优函数。
  4. 检查匹配结果。如果最优函数有多个,二义性; 最优函数访问私有成员等等。

实参演绎

在实参演绎过程中,每个实参-参数对的分析都是独立的。

template<typename T> void f(T);
template<typename T> void g(T&);
template<typename T> void r(T&& param);

double x[20];
int const seven = 7;
int y = 4;
int& ry = y;

f(x);               // T 被演绎成 double* , double [] decay 成 double*
f(seven);           // T 被演绎成 int,const丢失
f(7);               // T 被演绎成 int.
f(ry)               // T 被演绎成 int.
g(x);               // T 被演绎成 double[20]
g(seven);           // T 被演绎成 int const
g(7);               // ERROR!!! 不能把右值 7 传给 int&
g(ry);              // T 被演绎成 int

r(seven);           // seven 是左值,T和 param 都被演绎成 int const&
r(y);               // y是左值, T 和 param 都被演绎成 int&
r(ry);              // ry 是左值, T 和 param 都被演绎成 int&
r(7);               // 7 是右值, 所以 T 是 int, param 是 int&&

具体的实参演绎(模板类型推导)规则,可以参照 模板类型推导

SFINAE原则: 实参演绎的过程中如果发生不匹配的,或者匹配后使用错误的类型操作的,并不代表发生了ERROR,只需跳过这个模板,寻找下一个模板进行匹配即可。

函数匹配

匹配优先级(高到低)说明
完美匹配参数类型 和 实参类型完全相同,或者参数的类型是引用(const 引用)。 constnon-const属性也会存在完全匹配的差异。
decay如 数组类型 转化(decay)为指针类型; 或者 int 转化为 const int
提升匹配占位少的整数类型转换为占位多的类型。如bool -- int 或者 float -- double
类型转换的匹配包含任何种类的标准类型转换。如int -- float,但不包含隐式调用的类型转换运算符和单参数构造函数(所以要加explicit禁用)
用户自定义类型转换匹配允许任何可行的隐式类型转换
函数模板特化的标准匹配
函数模板的匹配
省略号的匹配
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值