使用 template 关键字引入模板: template void fun(T) {…}

    • 函数模板的声明与定义

      1. template <typename T> // 模板形参 --> 编译期确定
      2. void fun(T) // 函数形参 --> 运行期确定
      3. {
      4. // 定义,应该避免重复定义
      5. }
    • typename 关键字可以替换为 class ,含义相同

    • 函数模板中包含了两对参数:函数形参 / 实参;模板形参 / 实参

    函数模板的显式实例化:fun(3)

    • 实例化会使得编译器产生相应的函数(函数模板并非函数,不能调用
    • 编译期的两阶段处理 (和普通的函数是不一样的)

      • 模板语法检查
        - 模板实例化
    • 模板必须在实例化时可见——翻译单元的一处定义原则

    • 注意与内联函数的异同

    模板实参的类型推导
    – 如果函数模板在实例化时没有显式指定模板实参,那么系统会尝试进行推导
    – 推导是基于函数实参(表达式)确定模板实参的过程,其基本原则与 auto 类型推导相似
    ● 函数形参是左值引用 / 指针:
    – 忽略表达式类型中的引用
    – 将表达式类型与函数形参模式匹配以确定模板实参
    ● 函数形参是万能引用
    – 如果实参表达式是右值,那么模板形参被推导为去掉引用的基本类型
    – 如果实参表达式是左值,那么模板形参被推导为左值引用,触发引用折叠
    ● 函数形参不包含引用
    – 忽略表达式类型中的引用
    – 忽略顶层 const
    – 数组、函数转换成相应的指针类型