一、类模板特化
特化相反的是泛化也就是可以随便指定类型
特化:对特殊的类型,进行特殊的对待。给他开小灶,给他写适合他的专用代码,必须现有泛化版本,才能有特化版本。只要有特化,一定先存在泛化。
1.类模板全特化
1.1常规全特化
当T U这两个类型模板参数都为int 类型时。我们希望针对这两个类型做一个特化版本。
全特化,所有TU类型模板参数,都得用具体的类型代表。全特化以后所有类型模板参数都用int代表。所以template 后边的<>为空了。特化版本代码,编译器会优先选择调用。
#include <iostream>
using namespace std;
template <typename T, typename U>
struct TC//泛化的TC类模板
{
TC()
{
cout << "泛化版本构造函数" << endl;
}
void testfunc()
{
cout << "泛化版本" << endl;
}
};
template <>
struct TC<int, int>
{
TC()
{
cout << "int int 特化版本构造函数" << endl;
}
//在这里可以为该版本的特化版本做处理。
void testfunc()
{
cout << "int int的特化版本" << endl;
}
};
template <>
struct TC<double, int>
{
//在这里可以为该版本的特化版本做处理。
void testfunc()
{
cout << "double int的特化版本" << endl;
}
};
int main()
{
TC<char, int> tc;
tc.testfunc();
TC<int, int> tc1;
tc1.testfunc();
TC<double, int> tc2;
tc2.testfunc();
}
1.2特化成员函数
因为我们特化了double double类型的testfunc函数 所以我们调用的时特化的testfunc函数
#include <iostream>
using namespace std;
template <typename T, typename U>
struct TC//泛化的TC类模板
{
TC()
{
cout << "泛化版本构造函数" << endl;
}
void testfunc()
{
cout << "泛化版本" << endl;
}
};
template<>
void TC<double, double>::testfunc()
{
cout << "double double的testfunc()函数特化版本" << endl;
}
int main()
{
TC<double, double> tc3;
tc3.testfunc();
return 0;
}
2类模板偏特化(局部特化)
偏特化从两个方面说起,一个是从模板参数数量上,一个是从模板参数的范围上
2.1模板参数数量
从参数模板数量上进行偏特化。我们现在绑2个类型模板参数。留一个模板类型参数,留下U,另外两个绑定到具体类型,所以只剩下U
#include <iostream>
using namespace std;
template<typename T, typename U, typename W>
struct TCP
{
void testfunc()
{
cout << "TCP------>泛化版本" << endl;
}
};
template<typename U>
struct TCP<int, U, double>
{
void testfunc()
{
cout << "TCP------>int, U, double 偏特化版本" << endl;
}
};
int main()
{
TCP<int, double, int> tcp;
tcp.testfunc();
TCP<int, double, double> tcp1;
tcp1.testfunc();
}
2.2模板参数范围上
比如const int 的范围比int的范围更小。原来T 现在T* (从任意类型T缩小为指针类型T*)。原来是T 现在T&左值引用,或者现在T&&右值引用。局部特化,特化完了之后本质上还是一个模板。全特化,特化完了就相当于一个具体的类了
#include <iostream>
using namespace std;
template<typename T>
struct TC1
{
void testfunc()
{
cout << "TC1------>泛化版本" << endl;
}
};
//模板参数范围上的特化版本。
template<typename T>
struct TC1<const T>//const T的特化版本
{
void testfunc()
{
cout << "TC1------>const T的特化版本" << endl;
}
};
template<typename T>
struct TC1<T*>//T*的特化版本 告诉编译器,如果使用指针就调用这个版本
{
void testfunc()
{
cout << "TC1------>T*的特化版本" << endl;
}
};
template<typename T>
struct TC1<T&>//T&的特化版本
{
void testfunc()
{
cout << "TC1------>T&的特化版本" << endl;
}
};
template<typename T>
struct TC1<T&&>//T&&的特化版本
{
void testfunc()
{
cout << "TC1------>T&&的特化版本" << endl;
}
};
int main()
{
TC1<double> tc4;
tc4.testfunc();
TC1<double *> tc5;
tc5.testfunc();
TC1<const int *> tc6;
tc6.testfunc();
TC1<const int> tc7;
tc7.testfunc();
TC1<int&> tc8;
tc8.testfunc();
TC1<int&&> tc9;
tc9.testfunc();
}
二、函数模板特化
函数模板全特化
全特化函数模板实际上等价于实例化一个函数模板,不等价于函数重载。编译器会选择最最合适的调用。普通优先 特化版本, 泛化版本
#include <iostream>
using namespace std;
template <typename T, typename U>
void tfunc(T& tmprv1, U& tmprv2)
{
cout << "tfunc泛化版本" << endl;
cout << tmprv1 << endl;
cout << tmprv2 << endl;
}
//全特化版本。T=int U=double
template <>
void tfunc(int& tmprv1, double& tmprv2)//从左到右替换
{
cout << "---------------begin-----------------" << endl;
cout << "tfunc特化版本" << endl;
cout << tmprv1 << endl;
cout << tmprv2 << endl;
cout << "---------------end-----------------" << endl;
}
void tfunc(int& tmprv1, double& tmprv2)
{
cout << "tfunc的重载函数" << endl;
}
int main()
{
const char *p = "i love china!!";
int i = 12;
tfunc(p, i);
double db = 15.8f;
tfunc(i, db);
}