1.什么是模板
模板是C++支持参数化多态的工具,使用模板可以使用户为类或者函数声明一种一般模式,使得类中的某些数据成员或者成员函数的参数、返回值取得任意类型。
模板是一种对类型进行参数化的工具;通常有两种形式:函数模板和类模板;函数模板针对仅参数类型不同的函数;类模板针对仅数据成员和成员函数类型不同的类。
使用模板的目的就是能够让程序员编写与类型无关的代码。比如编写了一个返回类型为int参数为int的Add函数,这个函数就只能实现int 型,对double,字符这些类型无法实现,要实现这些类型的加法就要重新编写另一个Add函数。使用模板的目的就是要让这程序的实现与类型无关,比如一个Add模板函数,即可以实现int 型,又可以实现double型的加法。模板可以应用于函数和类。
2.函数模板
<1>函数模板:代表了一个函数家族,该函数与类型无关,在使用是被参数化,根据实参类型产生函数的特定模板。
函数模板的格式:
template
template <class T>
T Add(T left,T right)
{
return left+right;
}
int main()
{
cout<<Add(2,3)<<endl;// 5
cout<<Add(2.3,4.5)<<endl;// 6.8
cout<<Add('3','5')<<endl;// h
}
上面的代码中,模板被编译了两次:
实例化之前,检查模板代码本身,查看是否会出现语法错误,如:遗漏分号
实例化期间,检查模板代码,查看是否所有的调用都有效,如:实例化不支持某些函数调用。
cout<<Add(2.3,(int)4.5)<<endl;//如果你调用函数是对参数进行类型转化,就会报错。
注意:模板函数在推演时不支持类型转化。
<2>模板参数
函数模板有两种类型参数:模板参数和调用参数。
模板形参又分为:类型形参和费类型形参。
所有模板形参的前面必须加class或者typename关键字。
注意:在函数模板内部不能定义缺省的模板实参。
<3>非类型的模板参数
非类型的模板参数是模板内部定义的敞亮,在需要常量表达式的时候,可以使用非类型的模板参数。如下例子。
<4>模板函数的重载
模板函数是可以支持重载的,下面举例说明。
template <class T>
T Max(const T& left,const T& right)
{
return left>right? left:right ;
}
template <class T>//每次定义函数模板时都应该定义这句话
T Max(const T&a,const T&b,const T&c)
{
return Max(Max(a,b),c);
}
int main()
{
cout<<Max(2,3)<<endl;
cout<<Max<>(2,3)<<endl;
cout<<Max(2,3,4)<<endl;
cout<<Max<>(2,3,4)<<endl;
cout<<Max<int>(2.0,4.0)<<endl;
cout<<Max(2.0,4.0)<<endl;
}
注意:函数的所有重载版本的声明都应该位于该函数被调用位置之前。
<5>模板函数的特化
特化格式:template<>
返回值 函数名
template<>
int complare <int>(int)//这样当你需要什么类型的函数就可以自己定义了。
//注意:在调用的时候,实参类型必须与特化版本函数的形参类型完全匹配。