函数模板
模板是指将类型参数化,而模板的处理一般在编译阶段完成
template <class 形参名,class 形参名,......>
返回类型 函数名(参数列表){函数体}
template<typename T>
T Sum(T a,T b) //设计了一个函数模板
{
return a+b;
}
int main()
{
Sum<int>(10,20); //调用函数T,实例化(调用在后台生成。生成的代码为模板函数)
return 0;
}
模板的实参推演:
template<typename T>
T Sum(T a,T b)
{
return a+b;
}
int main()
{
Sum<int>(10,20);
Sum(10.1,20);//模板的实参推演,根据实参推演如果有两种类型的数据,有二义性 报错
return 0;
}
注意事项:不能让代码产生二义性;有实参才能推演
模板的特例化(专用化)
template<typename T>
int func(T, T) {...}; //原始的、最通用的版本
template<typename T>
class C
{
void bar() {...}
};
template<> //正在特例化一个模板
void C<int>::bar() {...} //正在特例化C<int>的成员bar,可以有新的函数体
注意事项:模板类型不能满足特殊类型的需求
特殊化的调用优先级高于模板实例化
特例化应该符合模板的实例化逻辑
完全特例化 全特化 函数模板类模板 具体到某一个类型
部分特例化 偏特化 类模板 具体到一部分类型
模板的类型参数:
template <typename T, size_t MAX_SIZE = 10> //带缺省模板参数
class SeqList
{
public :
SeqList();
private :
T _array [MAX_SIZE];
int _size ;
};
template <typename T, size_t MAX_SIZE>
SeqList <T, MAX_SIZE>::SeqList ()
: _size(0)
{}
void Test ()
{
SeqList<int > s1;
SeqList<int , 20> s2;
}
非类型的模板函数参数
template <class T, int value>
T Add (const T& x )
{
return x + value;
}
当要使用基于值的模板时,必须显式地指定这些值,才能够对模板进行实例化,并获得最终代码
模板的非类型参数:
函数模板和类模板,模板参数并不局限于类型,普通值也可以作为模板参数
非类型的类模板参数