一.模板的概念
模板就是实现代码重用机制的一种工具,他可以实现类型参数化,即把类型定义为参数。模板的定义一般放在头文件中
模板的调用
模板可以分为函数模板和类模板。
对于函数模板,当编译系统发现一个对应的函数调用时,将根据实参的类型来确定是否匹配函数模板中对应的形参,然后生成一个重载函数,该重载函数就被称为模板函数。函数模板与类类似,是模板的定义;模板函数与对象类似,是函数模板的实例。
同样对于类模板,只是一个模板的定义,而模板类才是创建出来的类
二..函数模板
1.函数模板的定义格式
template <class T1,class T2> // template <class 类型参数名1,class 类型参数名2...>
T1 fun(T1 a,T2 b) // 函数返回类型 函数名(形参表)
{ // {
... // 函数体
} // }
(1)类型参数名既可以代表基本数据类型,也可以代表类
(2)class可以换成 typename
(3)如果在全局中声明了一个与模板参数同名的对象函数或类型,该全局名将被隐藏
(4)模板参数可以是非类型参数,及常量表达式
2.模板函数
模板函数的调用格式如下
函数返回值类型 变量1=函数名 <类型参数1,类型参数2...>(实参表)
int min=fun<int,int>(2,3)
3.函数模板的异常处理
当模板形参与各模板实参之间不一致时,就会产生异常。
template <class T>
void min(T &a,T &b)
{
return ((a<b)?a:b);
}
int func(int a,char b)
{
min(a,b); //异常
min(b,a); //异常
}
可以通过非模板函数重载函数模板来解决
C++中,函数模板与同名的非模板函数重载时,遵循以下调用原则
(1)寻找一个参数完全匹配的函数,若找到,就调用它。若参数完全匹配的函数多于一个,则这个调用是一个错误的调用
(2)寻找一个函数模板,将其实例化生成一个匹配的模板函数,若找到,就调用它
(3)若上两条都失败,则使用函数重载的方法,通过类型转换产生参数匹配,若找到,就调用它
(4)若上面三条都失败,则这次调用是一个错误的调用
三.类模板
1.类模板的定义
template <class T,int N> //template <class 类型参数名, class 类型参数名,非类型参数 变量>
class S //class 类名
{ //{
private: //
int a; //
T b; // 类定义
... //
}; //}
如果类的成员函数要在类的声明之外定义,则它必须是模板函数,定义形式如下
template <class T,int N> //template<class 数据类型参数>
int S<T,N>::function(int a,T b) //数据类型参数 类名<数据类型参数>::函数名(数据类型参数 形参1,数据类型参数 形参2)
{ //{
... // 函数体
}; //}
2.模板类
类模板的实例化如下
S<int,100> C; //类名<类型参数名,非类型参数> 对象名;
类模板的特化
就是希望对特殊的类型参数,做特殊的处理
template <>
class S<std::string> //特化类
{
private:
std::deque<std::string> elements;
...
};