-
多参数类模板,类模板可以定义多个不同类型的参数
template <typename T1,typename T2> class Test { public: void add(T1 a,T2 b); } //使用方式 //需要指定每一个类型参数 //int --->T1 //float--->T2 Test<int,float> t;
-
令人惊讶的特性:类模板可以被特化
-
指定类模板的特定实现
-
部分类型参数必须显示指定
-
根据类型参数分开实现类模板
-
如下图所示,我们指定实际类型参数时,如果T1,T2是相同的类型,编译器会优先选择右边的类模板的实现,这两个类模板不会发生同名冲突的问题,编译器会把它们理解为同一个模板,只是根据类型参数来选择是使用哪一个模板。
-
类模板的特化类型
-
部分特化---用特定规则约束类型参数(即使特殊了,参数仍然是一个泛指类型)
-
完全特化---完全显示指定类型参数
-
如下图所示为完全特化:如果要使用Test类模板的时候完全显示指定泛指类型T1,T2都为int的时候,编译器会选择使用右边的完全特化的类模板来实现。
-
类模块特化注意事项
-
特化只是模块的分开实现,本质上是同一个类模块。
-
特化模块的使用方式是统一的,必须是显示指定每一个类型参数
-
范例程序
#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=" << a + b << endl; } }; template <typename T> //当Test类型参数完全相同时,使用这个类模板来实现 //编译器不会把它当成一个新的模板,只会把它看成Test模板的一种特殊的实现。 //部分特化 class Test<T, T> { public: void Add(T a, T b) { cout << "void Add(T a, T b)" << endl; cout << "a+b=" << a + b << endl; } }; //当Test类型参数都为void*类型是,使用这个类模板来实现 //完全特化 template < > class Test<void*, 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 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=" << *a + *b << endl; } }; int main() { Test<int, float> t1; Test<long, long> t2; Test<void*, void*> t3; Test<int*, double*> t4; int a = 2; double b = 3.14; t1.Add(1,2.5); t2.Add(2,3); t3.Add(NULL,NULL); t4.Add(&a,&b); }
-
运行结果
void Add(T1 a,T2 b) a+b=3.5 void Add(T a, T b) a+b=5 void add(void* a,void* b) Error to add void* Param void Add(T1* a,T2* b) *a+*b=5.14
-
问题
-
类模板特化与重定义有区别吗?
-
函数模板可以特化吗?
-
重定义和特化的不同
-
重定义:一个类模板和一个新类(或者两个类模板),使用的时候需要考虑如何选择的问题。
-
特化:以统一的方式使用类模板和特化类,编译器自动优先选择特化类
-
函数模板只支持类型参数完全特化
template <template T> //函数模板定义 bool Equal(T a,T b) { return a==b; } //函数模板完全特化 template < > bool Equal<void*>(void* a,void* b) { return a==b; }
-
范例程序
// 函数模板特化实验.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 // #include <iostream> #include <string> using namespace std; template <typename T1,typename T2> bool Equal(T1 a,T2 b) { cout << "bool Equal(T1 a,T2 b)" << endl; return a == b; } //函数模板完全特化 template <> bool Equal<double>(double a,double b) { const double detla = 0.0000000000001; double r = a - b; cout << "bool Equal<double>(double a,double b)" << endl; return (-detla < r) && (r < detla); } bool Equal(double a,double b) { const double detla = 0.0000000000001; double r = a - b; cout << "bool Equal(double a,double b)" << endl; return (-detla < r) && (r < detla); } int main() { //调用的是函数模板 cout << Equal(1, 2) << endl; //默认调用全局函数 cout << Equal(0.1,0.1) << endl; //调用特化后的函数模板 cout << Equal<double>(0.2, 0.2) << endl; //带个<>号,告诉编译器放弃全局函数,使用函数模板 cout << Equal<>(0.4, 0.5) << endl; }
-
运行结果
bool Equal(T1 a,T2 b) 0 bool Equal(double a,double b) 1 bool Equal<double>(double a,double b) 1 bool Equal<double>(double a,double b) 0
-
工程中的建议
当需要重载函数模块时,优先考虑使用模板特化。
当模板特化无法满足需求时,再使用函数重载。
-
小结
-
类模板可以定义任意多个不同的类型参数
-
类模板可以被部分特化和完全特化
-
特化的本质是模板的分开实现
-
函数模板只支持完全特化
-
工程中使用模板特化代替类(函数)重定义
来源:https://www.cnblogs.com/chengeputongren/p/12274603.html