RT
//类模板与模板特化接口说明 20190903
template<typename T>
void f1(T a, T b) {
}
// 函数模板特化类型,实例化形参数目必须与函数模板匹配
template<>
void f1<int>(int a, int b) {
}
template<typename T, typename T2>
void f1(T2) {
}
template<>
//void f1<int,char>(char) { //这个与下面等价 20190908
void f1<int>(char) { //T2通过形参已经指定,可以不用显示指定了:f2<int, char> 20190908
}
template<>
void f1<int,char*>(char*) {
}
//(1)类模板
template<typename T, typename T2>
struct A {
void f(T) {
}
//(2)成员模板
//成员模板可以有不同的函数接口,这里原f一个形参,成员模板f有3个形参
template <typename FT>
void f(FT t1, int i, double) {
t1 = i;
}
void f2(T);
template<typename MT>
void f2(MT);
};
template<typename T, typename T2>
void A<T,T2>::f2(T) {
}
template<typename T, typename T2>
template<typename MT>
void A<T,T2>::f2(MT) {
}
//(5)特化成员不特化类
//特化类成员与函数模板特化一样:特化类型,实例化形参数目必须与函数模板匹配
template<>
void A<char,int>::f<char>(char) {
}
template<>
void A<double,int>::f<double>(double) {
}
template<>
template<>
void A<double,int>::f<double>(double, int, double) {
}
//(3)类模板部分特化
//部分特化和类特化只要实例化形参数目与原类模板相同即可,即本例有2个实例化形参数目
//类内部函数接口可以不同,甚至定义不同的函数都没关系,因为实际上实例化出来是不同的类了
template<typename T, typename T2>
struct A<T(T2),int> {
void f(T, T2) {
}
};
//(4)类模板特化
template<>
struct A<int,int> {
void f2(int, char);
};
void A<int,int>::f2(int, char) {
}
int main() {
}
 
如果A <int,double> a; a.f2(1);则会调用类模板成员函数void f2(T),不会调用成员模板void f2(MT)
如为a.f2(1.2)则会调用成员模板void f2(MT)