Step By Step(C++模板重载和特化)
[来源] 达内 [编辑] 达内 [时间]2012-09-13
函数重载是一个非常通用亦非常容易理解的编程基础概念,既函数名相同而函数签名不同的一组函数,在实际的调用中,编译器会根据函数参数的不同自动选择最为合适且最为特化的函数。
一、模板函数重载:
&
nbsp; 函数重载是一个非常通用亦非常容易理解的编程基础概念,既函数名相同而函数签名不同的一组函数,在实际的调用中,编译器会根据函数参数的不同自动选择最为合适且最为特化的函数。在推演的过程中,如果出现多个函数均符合该调用规则,编译器将根据其内置的特化规则,选择最为特殊的函数作为候选函数。然而如果仍有多个候选函数的话,编译器将报出二义性错误。和普通函数一样,在C++中模板函数也同样支持函数重载的功能,甚至可以将模板函数与普通函数混合在一起,以达到更为灵活的函数重载的效果。
在这里,我们对于函数重载的概念本身将不再做过多的赘述了,而是将重点放在模板函数重载的应用场景和应用技巧上。下面我将给出一个利用模板函数重载计算哈希值的代码示例:
1 #include <stdio.h> 2 3 template<typename T> 4 int hash_code(T v) { 5 return v.hashCode() * 2; 6 } 7 8 template<typename T> 9 int hash_code(T* v) { 10 return v->hashCode(); 11 } 12 13 int hash_code(const int v) { 14 return v + 100; 15 } 16 17 class HashClass { 18 public : 19 HashClass(int v) : _v(v) {} 20 int hashCode() { 21 return _v + 200 ; 22 } 23 24 private : 25 int _v; 26 }; 27 28 int main() { 29 HashClass c1(10 ); //调用的是template<typename T> int hash_code(T v) 30 printf(" The hash value is %d\n" ,hash_code(c1)); 31 HashClass c2(20 ); //调用的是template<typename T> int hash_code(T* v) 32 printf(" The hash value is %d\n" ,hash_code(&c2)); 33 int i3 = 30; // 调用的是int hash_code(const int v) 34 printf(" The hash value is %d\n" ,hash_code(i3)); 35 return 0; 36 } 37 38 // The hash value is 420 39 // The hash value is 220 40 //The hash value is 130
二、模板类特化:
对于模板类而言,也同样存在和模板函数重载类似的应用场景,但是在模板类中则是以模板类特化的方式存在。在下面的示例代码为生产者-消费者的任务缓冲队列,当清空队列中的已有元素时,亦需考虑如何释放元素对象本身可能占用的系统资源。这里会根据不同的元素类型,给出不同的元素释放类。< div style="background-color: rgb(245, 245, 245); font-family: 'Courier New'; font-size: 12px; border: 1px solid rgb(204, 204, 204); padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; color: rgb(0, 0, 0); font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 18px; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; " class="cnblogs_code">
1 #include <stdio.h> 2 #include <vector> 3 4 using namespace std; 5 6 class Runnable { 7 public : 8 virtual void release() { 9 delete this ; 10 } 11 }; 12 13 class Closable { 14 public : 15 virtual void close() { 16 _db.close(); 17 delete this; 18 } 19 private: 20 db_env _db; 21 }; 22 23 template<typename T> 24 class List { //1 25 public : 26 void clear() { 27 _taskList.clear(); 28 } 29 private : 30 vector<T> _taskList; 31 }; 32 33 template<typename T> 34 class List<T*> { //2 35 public : 36 void clear() { 37 for (int i = 0 ; i < _taskList.size(); ++i) 38 delete _taskList[i]; 39 _taskList.clear(); 40 } 41 private : 42 vector<T*> _taskList; 43 }; 44 45 template<> 46 class List<char*> { // 347 public : 48 void clear() { 49 for (int i = 0 ; i < _taskList.size(); ++i) 50 delete [] _taskList[i]; 51 _taskList.clear(); 52 } 53 private : 54 vector<char *> _taskList; 55 }; 56 57 template<> 58 class List<Runnable*> { //4 59 public : 60 void clear() { 61 for (int i = 0 ; i < _taskList.size(); ++i) 62 _taskList[i]->release(); 63 _taskList.clear(); 64 } 65 private : 66 vector<Runnable*> _taskList; 67 }; 68 69 template<> 70 class List<Closable*> { //5 71 public : 72 void clear() { 73 for (int i = 0 ; i < _taskList.size(); ++i) 74 _taskList[i]->close(); 75 _taskList.clear(); 76 } 77 private : 78 vector<Runnable*> _taskList; 79 }; 80 81 int main() { 82 List<Runnable*> listRunnable; //调用No 4 83 List<Closable*> listClosable; // 调用No 5 84 List<int > listInt; //调用No 1 85 List<int *> listIntPointer //调用No 2 86 List<char *> listCharPointer; //调用No 3 87 return 0; 88 }