一、类模板的全特化与偏特化:
- 均要求有一个主模板类(里面全是未知Type参数的正常模板类)
- 全特化是把主模板中所有未知类型变为确定类型
- 偏特化的第一种形式:保留一部分未知类型,确定一部分类型;
- 偏特化的第二种形式:限定传入类型的范围
- 把template<typename T1,typename T2>里的东西搬到class<T1*,T2*>里面去限定
template <class T1,class T2>
class Test
{
};
//主模板
template <>
class Test<int,double>
{
}
//全特化
template <class T1,class T2>
class Test
{
};
//主模版
template < class T>
class Test < T,int >
{
};
//偏特化1
template <class T1,class T2>
class Test
{
};
//主模版
template <class T1,class T2>
class Test <const T1*,const T2*>
{
};
//偏特化2
二、函数模板的全特化
- 函数模板没有偏特化。所谓的“函数偏特化”其实是名字相同的两个不一样的函数模板。
- 函数模板允许参数列表中的某些参数类型使用模板,某些确定。就如同类允许某些变量、返回值使用模板,某些变量确定一样。
- 函数模板全特化时,如果主模板的参数列表做了限定,全特化模板必须与其保持一致的形式。
template<class T,class Y>
bool Isequal(const T& p1, const Y& p2)
{
return p1 == p2;
}
//函数主模板,且对参数进行了范围限定
template<>
bool Isequal<int,double>(const int& p1, const double& p2)
{
return p1 == p2;
}
//全特化,注意括号里两个形参类型必须对应特化完的两个具体类型,且范围限定也要一致
template
bool Isequal(X p1, string p2){
return p1 == p2;
}
//注意,这不是偏特化!特化的前提条件:函数名之后要有<>才是特化。故这是同名的另一模板,把原模板去掉并不影响编译,不使用X也不影响编译;
/*template
bool Isequal<S,double>(S p1, double p2){
return p1 == p2;
}
*/
//此处"偏特化"编译不通过:
三.调用顺序
当给定语句与多个函数匹配时,调用顺序:
形参完全匹配的非模板函数>形参完全匹配的全特化函数模板>未特化的函数模板
using namespace std;
template <class T1,class T2>
void test(T1 a,T2 b)
{
cout<<"主模板";
}
template <>
void test<int,double>(int a,double b)
{
cout<<"全特化";
}
void test(int a,double b)
{
cout<<"不是模板";
}
int main()
{
test(5,4.9999);
}