一、多参数的类模板
1、类模板可以定义任意多个不同类型的参数
2、类模板可以被特化
(1)、指定类模板的特定实现
(2)、部分类型参数必须显示指定(如class Test<T, T> 就是现实指定T)
(3)、根据类型参数分开实现类模板(同一个模板根据需要用不同方式来实现而已)
(4)、类模板的特化类型
A、部分特化:用特定规则约定类型参数(仍然存在类型参数)
B、完全特化:完全显示指定类型参数
(5)、特化注意事项
A、特化只是模板的分开实现(实现的功能都一样,本质上还是同一个模板,根据需要使用不同的实现方式而已)
B、特化类模板的使用方式是统一的(定义对象时必须显示指定每一个参数的类型)
#include <iostream> #include <string> using namespace std; template < typename T1, typename T2 > class Test { public: void add(T1 a, T2 b) { cout << "void add(T1 a, T2 b)" << endl; cout << a + b << endl; } }; template < typename T1, typename T2 > //部分特化,因为还有类型参数 class Test < T1*, T2* > // 关于指针的特化实现,特化时在这里显示指定参数的类型,如这里的< T1*, T2*>
{ // 用以实现上述模板的特殊情况,本质上还是同一个模板 public: void add(T1* a, T2* b) { cout << "void add(T1* a, T2* b)" << endl; cout << *a + *b << endl; } }; template < typename T >//部分特化 class Test < T, T > // 当 Test 类模板的两个类型参数完全相同时,使用这个实现 { public: void add(T a, T b) { cout << "void add(T a, T b)" << endl; cout << a + b << endl; } void print()//特化类可以有自己的成员函数 { cout << "class Test < T, T >" << endl; } }; template < >//完全特化 class Test < void*, void* > // 当 T1 == void* 并且 T2 == void* 时 { public: void add(void* a, void* b) { cout << "void add(void* a, void* b)" << endl; cout << "Error to add void* param..." << endl; } }; int main() { Test<int, float> t1; Test<long, long> t2;//选择参数相同的特化类模板 Test<void*, void*> t3;//选择void*时的特化类模板(优先于两个参数相同的那个) t1.add(1, 2.5); t2.add(5, 5); t2.print(); t3.add(NULL, NULL); Test<int*, double*> t4;//选择指针时的版本 int a = 1; double b = 0.1; t4.add(&a, &b); return 0; } //输出结果 /* void add(T1 a, T2 b) 3.5 void add(T a, T b) 10 class Test < T, T > void add(void* a, void* b) Error to add void* param... void add(T1* a, T2* b) 1.1 */
二、特化与重定义的区别
1、重定义
(1)、一个类模板和一个新类(或者两个类模板)
(2)、使用的时候需要考虑如何选择的问题
2、特化
(1)、以统一的方式使用类模板和特化类(定义对象是显示指定参数)
(2)、编译器自动优先选择特化类
(3)、函数模板的特化(只能完全特化)
3、工程中的建议
(1)、当需要重载函数模板时,优先考虑使用模板特化
(2)、当特化无法满足需求时,再考虑函数模板
#include <iostream> #include <string> using namespace std; template < typename T1, typename T2 > class Test { public: void add(T1 a, T2 b) { cout << "void add(T1 a, T2 b)" << endl; cout << a + b << endl; } }; template < typename T1, typename T2 > class Test < T1*, T2* > // 关于指针的特化实现 { public: void add(T1* a, T2* b) { cout << "void add(T1* a, T2* b)" << endl; cout << *a + *b << endl; } }; template < typename T > class Test < T, T > // 当 Test 类模板的两个类型参数完全相同时,使用这个实现 { public: void add(T a, T b) { cout << "void add(T a, T b)" << endl; cout << a + b << endl; } void print() { cout << "class Test < T, T >" << endl; } }; /* template < > class Test < void*, void* > // 当 T1 == void* 并且 T2 == void* 时 { public: void add(void* a, void* b) { cout << "void add(void* a, void* b)" << endl; cout << "Error to add void* param..." << endl; } }; */
//类模板的重定义,本质上已经是一个新的类 class Test_void { public: void add(void* a, void* b) { cout << "void add(void* a, void* b)" << endl; cout << "Error to add void* param..." << endl; } };
/************************ 函数 *******************************/ template < typename T> bool Equal(T a, T b) { cout << "bool Equal(T a, T b)" << endl; return a == b; } //函数特化 template < >//只能完全特化 bool Equal(double a, double b) { cout << "bool Equal(double a, T double)" << endl; const double delta = 0.00000000000001; double r = a - b; return (-delta < r) && (r < delta); } //函数重定义 bool Equal(double a, double b) { const double delta = 0.00000000000001; double r = a - b; return (-delta < r) && (r < delta); } int main() { //Test<void*, void*> t3; Test_void t3; t3.add(NULL, NULL); cout << endl; cout << Equal<>(1.2, 0.6) << endl;//< > 限定编译器只匹配模板 return 0; }
四、小结
(1)、类模板可以定义任意多个类型不同的参数
(2)、类模板可以被部分特化和完全特化
(3)、特化的本质是模板的分开实现
(4)、函数模板只支持完全特化
(5)、工程中用模板特化代替类(函数)重定义