C++模板之函数模板

泛型编程

编写与类型无关的逻辑代码,是代码复用的一种手段。模板是泛型编程的基础

模板

代表一个函数家族,该函数与类型无关,在使用时被参数化,根据实参类型产生函数的特定类型版本(它本身不是类或函数)

模板函数的格式

这里写图片描述

模板的实例化

产生模板特定类型的过程称为函数模板的实例化

template <typename T>
T Add(T left,T right)
{
    return left + right;
}
int main()
{
    Add(1,2);
    Add(1.0,2.0);
    Add('1','1');
    Add(1,1.0);//error:模板参数“T”不明确  
    //模板函数不会进行类型转换
    Add<int>(1, '1');//显式实例化
    Add<double>(1, 1.0);
    Add(1,(int) 1.0);//隐式实例化
    return 0;
}
模板的实参推演

从函数实参确定模板形参类型和值得过程称为模板实参推断

类型形参转换

一般不会转换实参已匹配以有的实例化,相反会产生新的实例;
编译器只会执行两种转换:1.const转换;2.数组或函数到指针的转换

  • const转换

    接收const引用或const指针的函数可以分别用非const对象的引用或者指针来调用

  • 数组或函数到指针的转换

    如果模板形参不是引用类型,则对数组或函数类型的实参应用常规指针转换。数组实参将当做指向其第一个元素的指针,函数实参当做指向函数类型的指针

模板形参
  • 模板类型参数
typedef double T;
//模板形参的名字在同一模板中只能使用一次
template <typename T, typename T>// error C2991: 重定义 模板 参数“T”
//所有模板形参前必须加上class/typename关键字修饰
template <typename T,U>//error C2061: 语法错误: 标识符“U”
template <typename T = int> //可以指定缺省的模板实参
T Add(T left=1, T right=2 )//缺省的调用参数
{
    cout << "T type = " << typeid(T).name() << endl;//打印模板参数T的类型
    return left + right;
}
T val;//全局变量
int main()
{
    Add();
    cout << "T type = " << typeid(T).name() << endl;//打印全局变量的类型
    return 0;
}

这里写图片描述

模板形参的名字只能在模板形参之后到模板声明或定义的末尾使用

  • 非模板类型参数
    模板内部定义的常量
template <typename T = int ,int N = 10>  //N:非模板类型参数
void Funtest(T(&_array)[N])   //数组引用
{
    for (int i = 0; i < N; ++i)
    {
        _array[i] = 0;
    }
}
int main()
{
    const int c = 3;
    int a[4];
    int b[c + 1];  
    Funtest(a);
    Funtest(b);
    return 0;
}
模板函数和同名非模板函数
int Max(const int& a, const int& b)   //同名的非模板函数和模板函数可以同时存在
{
    return a > b ? a : b;
}
template <typename T>
T Max(const T& a,const T& b)
{
    return a > b ? a : b;
}
template <typename T1, typename T2>
T1 Max(const T1& a, const T2& b)
{
    return a > b ? a : b;
}
int main()
{
    Max(1, 2);//优先调用非模板函数
    Max<>(1, 2);//显示指定,只能调用模板
    Max(1, 2.0);//优先调用优化模板template <typename T1, typename T2>
    return 0;
}
模板特化
  • 特化格式
    这里写图片描述
template <typename T>//模板实例
int compare(T a,  T b)//比较了地址
{
    if (a < b)
        return -1;
    if (a>b)
        return 1;
    return 0;
}
template <>//模板特化    在模板实例之后
//特化的声明必须与特定的模板相匹配
//int compare<const char*>(char* p1, char*  p2)//error :不是函数模板的专用化
int compare<const char*>(const char* p1, const char*  p2)
{
    return strcmp(p1,p1);
}
int main()
{
    char* p1 = "abcd";
    char* p2 = "abce";
    const char* p3 = "abcd";
    const char* p4 = "abce";
    cout << compare(p1, p2) << endl;
    cout << compare(p3, p4) << endl;
    return 0;
}
模板重载
template <typename T>
T Max(const T& a, const T& b)
{
    return a > b ? a : b;
}
template <typename T>
T Max(const T& a, const T& b, const T& c)//重载
{
    return Max(Max(a, b), c);
}
int main()
{
    Max(1, 2);
    Max(1, 2, 4);
    return 0;
}
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值