使用 template 关键字引入模板: template
函数模板的声明与定义
template <typename T> // 模板形参 --> 编译期确定
void fun(T) // 函数形参 --> 运行期确定
{
// 定义,应该避免重复定义
}
typename 关键字可以替换为 class ,含义相同
- 函数模板中包含了两对参数:函数形参 / 实参;模板形参 / 实参
函数模板的显式实例化:fun
- 实例化会使得编译器产生相应的函数(函数模板并非函数,不能调用)
编译期的两阶段处理 (和普通的函数是不一样的)
- 模板语法检查
- 模板实例化
- 模板语法检查
模板必须在实例化时可见——翻译单元的一处定义原则
- 注意与内联函数的异同
模板实参的类型推导
–
如果函数模板在实例化时没有显式指定模板实参,那么系统会尝试进行推导
–
推导是基于函数实参(表达式)确定模板实参的过程,其基本原则与 auto 类型推导相似
●
函数形参是左值引用 / 指针:
– 忽略表达式类型中的引用
– 将表达式类型与函数形参模式匹配以确定模板实参
●
函数形参是万能引用
– 如果实参表达式是右值,那么模板形参被推导为去掉引用的基本类型
– 如果实参表达式是左值,那么模板形参被推导为左值引用,触发引用折叠
●
函数形参不包含引用
– 忽略表达式类型中的引用
– 忽略顶层 const
– 数组、函数转换成相应的指针类型