文章目录
- 非类型模板参数
- 模板特化
- 函数模板特化
- 类模板特化
- 全特化
- 偏特化
- 模板的分离编译
- 模板总结
- 所有测试的代码
非类型模板参数
模板参数分类类型形参与非类型形参
1.类型形参即:出现在模板参数列表中,跟在class或者typename之类的参数类型名称。
2.非类型形参,就是用一个常量作为类(函数)模板的一个参数,在类(函数)模板中可将该参数当成常量来使用。
注意:
1.浮点数、类对象以及字符串是不允许作为非类型模板参数的。
2.非类型的模板参数必须在编译期就能确认结果。
模板特化
函数模板特化
通常情况下,使用模板可以实现一些与类型无关的代码,但对于一些特殊类型的可能会得到一些错误的结果,需要特殊处理。
函数模板的特化步骤:
- 必须要先有一个基础的函数模板
- 关键字template后面接一对空的尖括号<>
- 函数名后跟一对尖括号,尖括号中指定需要特化的类型
- 函数形参表: 必须要和模板函数的基础参数类型完全相同,如果不同编译器可能会报一些奇怪的错误。
注意:一般情况下如果函数模板遇到不能处理或者处理有误的类型,为了实现简单通常都是将该函数直接给
出。
类模板特化
全特化
全特化即是将模板参数列表中所有的参数都确定化。
偏特化
偏特化有以下两种表现方式:
1.部分特化
将模板参数类表中的一部分参数特化。
2.参数更进一步的限制
模板的分离编译
概念
一个程序(项目)由若干个源文件共同实现,而每个源文件单独编译生成目标文件,最后将所有目标文件链接起来形成单一的可执行文件的过程称为分离编译模式。
模板的声明与定义分离开,在头文件中进行声明,源文件中完成定义(这样是不行的,在链接的时候编译器会报错)
解决方法
- 将声明和定义放到一个文件 “xxx.hpp” 里面或者xxx.h其实也是可以的。推荐使用这种。
- 模板定义的位置显式实例化。这种方法不实用,不推荐使用。
模板总结
所有测试的代码
//template<class T>
//void Swap(const T& a, const T& b)
//{
// cout << "Swap(const T& a, const T& b)" << endl;
//}
//template<>
//void Swap<int>(const int& a, const int& b)
//{
// cout << "Swap<int>(const int& a, const int& b)" << endl;
//}
//void test_function_Special()
//{
// //函数模板特化
// double x1 = 0;
// int x2 = 0;
// double y1 = 0;
// int y2 = 0;
// Swap(x1, y1);
// Swap(x2, y2);
//}
//template<class T1,class T2>
//class Date
//{
//public:
// Date()
// {
// cout << "Date<T1,T2>" << endl;
// }
//private:
// T1 d1;
// T2 d2;
//};
//template<>
//class Date<int, double>
//{
//public:
// Date()
// {
// cout << "Date<int,double>" << endl;
// }
//private:
// int d1;
// double d2;
//};
//template<class T1, class T2>
//class Date
//{
//public:
// Date()
// {
// cout << "Date<T1,T2>" << endl;
// }
//private:
// T1 d1;
// T2 d2;
//};
//template<class T2>
//class Date<int,T2>
//{
//public:
// Date()
// {
// cout << "Date<int,T2>" << endl;
// }
//private:
// int d1;
// T2 d2;
//};
//template<class T1, class T2>
//class Date
//{
//public:
// Date()
// {
// cout << "Date<T1,T2>" << endl;
// }
//private:
// T1 d1;
// T2 d2;
//};
//template<class T1, class T2>
//class Date<T1*, T2*>
//{
//public:
// Date()
// {
// cout << "Date<T1*,T2*>" << endl;
// }
//private:
// T1 d1;
// T2 d2;
//};
//void test_calss_Special()
//{
// 全特化
// //Date<double, char> T1;
// //Date<int, char> T2;
// //Date<int, double> T3;
// //偏特化
// Date<double, char> T4;
// Date<int, char> T5;
// Date<int, double> T6;
// Date<int*, double*> T7;
//}
//int main()
//{
// //test_function_Special();
// test_calss_Special();
// return 0;
//}
非模板类型参数
//template<class T,int N = 10>
//class arry
//{
//private:
// //创建一个静态数组
// T a[N];
//};
//int main()
//{
// arry<int, 100> arr;
// return 0;
//}