特化的概念
特化,就是将泛型的东东搞得“具体化”一些,从字面上来解释,就是为已有的模板参数进行一些使其特殊化的指定,使得以前不受任何约束的模板参数,或受到特定的修饰或完全被指定了下来。
模板特化的分类
(1)针对特化的对象不同,分为两类:函数模板的特化和类模板的特化
全特化的标志:template <>然后是完全和模板类型没有一点关系的类实现或者函数定义。
全特化就是限定死模板实现的具体类型;
偏特化就是如果这个模板有多个类型,那么只限定其中的一部分。
全特化的标志:template <>
偏特化的标志:template <… …>
【说明】<>中写的是没有被特化的类型,举例子说明:
①如果<>里边是空的,则说明每个类型都被特化,因此就是全特化。
②如果<… …>里边不是空的,则… …就是没有被特化的类型
【注】
①模板函数只能全特化,没有偏特化(以后可能有);模板类是可以全特化和偏特化的。②全特化也就是定义了一个全新的类型,针对于类的全特化,“类中的函数”可以与模板类不一样
,也就是说生成了一个全新的类。
(2)针对特化的范围不同,分为两类:全特化和偏特化
偏特化:就是模板中的模板参数没有被全部确定,有部分参数类型需要编译器在编译时进行确定。
例1:函数模板的全特化
template <class T> //函数模板
int compare(const T &left, const T&right)
{
std::cout <<"in template<class T>..." <<std::endl;
return (left - right);
}
//函数模板的全特化代码见下面两种情况,一共有两种写法(这两种写法等价!):
//写法一
template < >
int compare<const char*>(const char* left, const char* right)
{
std::cout <<"in special template< >..." <<std::endl;
return strcmp(left, right);
}
//写法二
template < >
int compare(const char* left, const char* right)
{
std::cout <<"in special template< >..." <<std::endl;
return strcmp(left, right);
}
例2:类模板的偏特化
#include <iostream>
#include <cstring>
#include <cmath>
//类模板T
template<class T>
class Compare
{
public:
static bool IsEqual(const T& lh, const T& rh)
{
std::cout <<"in the general class..." <<std::endl;
return lh == rh;
}
};
//类模板的全特化float
template<>
class Compare<float>
{
public:
static bool IsEqual(const float& lh, const float& rh)
{
std::cout <<"in the float special class..." <<std::endl;
return std::abs(lh - rh) < 10e-3;
}
};
//类模板的全特化double
template<>
class Compare<double>
{
public:
static bool IsEqual(const double& lh, const double& rh)
{
std::cout <<"in the double special class..." <<std::endl;
return std::abs(lh - rh) < 10e-6;
}
};
【注】调用准则:先去全特化、偏特化中寻找匹配的函数;若找不到再去模板函数中去寻找。
int main(void)
{
Compare<int> comp1;
std::cout <<comp1.IsEqual(3, 4) <<std::endl;
std::cout <<comp1.IsEqual(3, 3) <<std::endl;
Compare<float> comp2;
std::cout <<comp2.IsEqual(3.14, 4.14) <<std::endl;
std::cout <<comp2.IsEqual(3, 3) <<std::endl;
Compare<double> comp3;
std::cout <<comp3.IsEqual(3.14159, 4.14159) <<std::endl;
std::cout <<comp3.IsEqual(3.14159, 3.14159) <<std::endl;
return 0;
}
例3:类模板的偏特化
//类模板T1、T2
template<class T1, class T2>
class A
{
}
//类模板的偏特化T1, int
template<class T1>
class A<T1, int>
{
}
【综合示例】
template<typename T1, typename T2>
class Test
{
public:
Test(T1 i,T2 j):a(i),b(j){cout<<"模板类"<<endl;}
private:
T1 a;
T2 b;
};
template<>
class Test<int , char>
{
public:
Test(int i, char j):a(i),b(j){cout<<"全特化"<<endl;}
private:
int a;
char b;
};
template <typename T2>
class Test<char, T2>
{
public:
Test(char i, T2 j):a(i),b(j){cout<<"偏特化"<<endl;}
private:
char a;
T2 b;
};
//那么下面3句依次调用类模板、全特化与偏特化:
Test<double , double> t1(0.1,0.2);
Test<int , char> t2(1,'A');
Test<char, bool> t3('A',true);
例4:函数模板的偏特化
而对于函数模板:只有全特化,不能偏特化!
//模板函数
template<typename T1, typename T2>
void fun(T1 a , T2 b)
{
cout<<"模板函数"<<endl;
}
//全特化
template<>
void fun<int ,char >(int a, char b)
{
cout<<"全特化"<<endl;
}
//函数不存在偏特化:下面的代码是错误的
/*
template<typename T2>
void fun<char,T2>(char a, T2 b)
{
cout<<"偏特化"<<endl;
}
*/