模板函数和模板类有的时候可能需要对传入的不同类型进行不同的处理,比如说有的模板传入int或double类型都可以处理,但是传入char型则会出错,这时就需要模板特化的方式。
类模板全特化:将模板类型里的所有类型参数全部具体指明之后处理
template<typename T,typrname C>
struct A
{
A(){cout<<"泛化版本构造函数"<<endl;}
void func()
{
cout<<"泛化版本"<<endl;
}
};
template<>
struct A<int,int>
{
A(){cout<<"int,int特化版本构造函数"<<endl;}
void func()
{
cout<<"int,int特化版本"<<endl;
}
};
template<>
struct A<double,double>
{
A(){cout<<"double,double特化版本构造函数"<<endl;}
void func()
{
cout<<"double,double特化版本"<<endl;
}
};
template<>中为空,代表所有类型都在下面特殊化处理,上面相当于对int,int和double,double两种类型进行了分别的处理,其他类型依然是泛化版本
int main()
{
A<int,double> a;//调用泛化构造函数
a.func();//调用泛化版本函数
A<int,int> a;//调用int,int特化构造函数
a.func();//调用int,int特化版本函数
A<double,double> a;//调用double,double特化构造函数
a.func();//调用double,double特化版本函数
}
若对只对其中一个成员函数进行特化处理:
template<>
void A<int,double>::func
{
cout<<"int,double特化版本函数"<<endl;
}
int main()
{
A<int,double> a;//调用泛化版本构造函数
a.func();//调用int,double特化版本函数
}
则只有调用此函数时,才会进入特化版本
类模板偏特化(局部特化):顾名思义,只特殊化几个参数或者一定的参数范围
1)基于模板参数数量的偏特化
template<typename T,typename C,typename D>
struct A
{
void func()
{
cout << "泛化版本" << endl;
}
};
template<typename C>
struct A<int,C,int>
{
void func()
{
cout << "int,C,int偏特化版本" << endl;
}
};
template<typename C>
struct A<double, C, double>
{
void func()
{
cout << "double,C,double偏特化版本" << endl;
}
};
int main()
{
A<double, int, int> a;
a.func();//调用泛化版本
A<int, char, int> b;
b.func();//调用int,C,int偏特化版本
A<double, int, double> c;
c.func();//调用double,C,double偏特化版本
}
template<>括号中存留的参数是依然可以任意填的参数。
2)基于模板参数范围
比如const int属于int的一个小范围,int *和const int*属于int的一个小范围,int&属于int的一个小范围,int&&属于int的一个小范围
template<typename T>
struct A
{
void func()
{
cout << "泛化版本" << endl;
}
};
template<typename T>
struct A<const T>
{
void func()
{
cout << "const T版本" << endl;
}
};
template<typename T>
struct A<T*>
{
void func()
{
cout << "T*版本" << endl;
}
};
template<typename T>
struct A<T&>
{
void func()
{
cout << "T&版本" << endl;
}
};
template<typename T>
struct A<T&&>
{
void func()
{
cout << "T&&版本" << endl;
}
};
int main()
{
A<int> a;
a.func();
A<const int> b;
b.func();
A<int *> c;
c.func();
A<const int *> d;
d.func();
A<int&> e;
e.func();
A<int&&> f;
f.func();
}
记住这种情况的template<>中还是要填上原有的大类型,且const T*属于T*不属于const T。
函数模板全特化:
template<typename T,typename C>
void func(T &a, C &b)
{
cout << "------------------------" << endl;
cout << "泛化版本" << endl;
cout << a << endl;
cout << b << endl;
cout << "------------------------" << endl;
}
template<>
void func(int &a, int &b)
{
cout << "------------------------" << endl;
cout << "int,int特化版本" << endl;
cout << a << endl;
cout << b << endl;
cout << "------------------------" << endl;
}
int main()
{
double a = 1.0;
double b = 2.0;
func(a, b);
int c = 3;
int d = 4;
func(c, d);
}
假如说存在非模板的重载函数,且其与特化的一个版本一样
template<typename T,typename C>
void func(T &a, C &b)
{
cout << "------------------------" << endl;
cout << "泛化版本" << endl;
cout << a << endl;
cout << b << endl;
cout << "------------------------" << endl;
}
template<>
void func(int &a, int &b)
{
cout << "------------------------" << endl;
cout << "int,int特化版本" << endl;
cout << a << endl;
cout << b << endl;
cout << "------------------------" << endl;
}
void func(int &a, int &b)
{
cout << "------------------------" << endl;
cout << "重载版本" << endl;
cout << a << endl;
cout << b << endl;
cout << "------------------------" << endl;
}
int main()
{
double a = 1.0;
double b = 2.0;
func(a, b);
int c = 3;
int d = 4;
func(c, d);
int e = 3;
int f = 4;
func<int, int>(e, f);
}
则在你不特地指明参数类型时,编译器会优先选择重载普通函数版本。
函数模板偏特化:
函数模板不能偏特化!!!!!!!!!!!!!