C++ 函数模板的使用

函数模板
  给出一个简单的例子,实现两个数相加,如下:

#include<iostream>
template<typename T>
T Sum(T a,T b)   //Sum为模板名
{
   return a+b;
}
int main()
{
   std::cout<<Sum<int>(10,20)<<std::endl;
   std::cout<<Sum<double>(10.1,20.1)<<std::endl;
   std::cout<<Sum<char>('0','2')<<std::endl;
   return 0;
}

  其中,< >为模板类型参数列表,template为模板标识关键字,typename用来定义类型。
注意:模板处理在编译阶段,做类型重定义。在调用点实例化,比如主函数中的第一次使用Sum模板,将 T 替换成 int 型之后,生成了模板函数,调用的是模板函数,而不是模板。
函数模板的编译过程:
  1.在模板的定义点,只编译模板头部。模板体不编译。
  2.在调用点实例化之后,编译模板函数。
函数模板实参推演过程

#include<iostream>

template<typename T>
T Sum(T a,T b)
{
    return a+b;
}
int main()
{
    Sum(10,20);//编译通过
    Sum(10,20.1);//编译报错
    return 0;
}

  上面的代码中,第一次使用Sum模板时,系统推演出实参的类型为 int 型,再用 int 型来实例化,因此可以编译通过。上述代码模板类型参数,一趟调用过程中,只能被一个类型替换,因此,在第二次调用时,由于传递的实参是 int 型和 double 型,编译器在实例化的时候产生了二义性,因此会报错。
模板的实参推演:
  1.不能让推演产生二义性。
  2.有实参。

函数模板的特例化

#include<iostream>

template<typename T>
bool Compare(const T a,const T b)
{
    return a>b;
}
int main()
{
    std::cout<<Compare<int>(10,20)<<std::endl;
    std::cout<<Compare<double>(10.2,20.3)<<std::endl;
    std::cout<<Compare<char*>("compare","computer")<<std::endl;//"compare"<"computer"  结果应该为0
    return 0;
}

运行结果如下:
在这里插入图片描述
  上述程序虽然编译可以通过,但是用char* 类型来实例化后的结果并不是我们想要的,因此,我们需要特殊处理。即函数模板的版本不能满足char* 类型的需求,需要特殊处理,也就是模板特例化。

#include<iostream>

template<typename T>
bool Compare(const T a,const T b)
{
    return a>b;
}
template<>
bool Compare<char*>(char* const a,char* const b)
{
    return strcmp(a,b)>0;
}
int main()
{
    std::cout<<Compare<int>(10,20)<<std::endl;
    std::cout<<Compare<double>(10.2,20.3)<<std::endl;
    std::cout<<Compare<char*>("compare","computer")<<std::endl;
    return 0;
}

运行结果如下:
在这里插入图片描述
注意:特例化版本必须满足和模板版本相同的逻辑。比如上述代码中特例化版本中const所加的位置,不能放在char* 类型之前。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值