模板编程,也叫“通用编程”或“泛型编程”,泛型编程即独立于任何特定类型的方式编写代码。
一般而言,模板分为:函数模板 和 类模板。
1. 函数模板
模板函数的定义格式:
template <模板参数列表>
返回类型 函数名(函数参数列表) { 函数实现 };
template <typename T> int function(T a, T b) { if (a < b) return -1; else if (a > b) return 1; }
函数模板的使用方式:
函数模板使用时,编译器会先判断哪个模板实参绑定到模板实参,一旦编译器确定了实际的模板实参,就称为实例化了函数模板的一个实例。
1 int main(int argc, char* argv[]) 2 { 3 int a = 1; 4 int b = 2; 5 short c = 9; 6 short d = 5; 7 8 int result = 0; 9 result= function <int> (a, b); // 显式的表示T实参类型 10 printf("type is int , result == %d ", result); 11 result = function <short> (c, d); // 显式的表示T实参类型 12 printf("type is short , result == %d ", result); 13 14 return 0; 15 }
由此可见, 一开始我们编写的只是一个“函数模板”, 要使用它需要先将它实例化为一个“模板函数”(如:function <int>)。
编译器在编译此程序的时候,为每个调用此模板的代码生成了一个函数。而且在后期的使用过程中,更加让我认识到:
a、函数模板并不是函数,它仅在编译时根据调用此模板函数时传递的实参类型来生成具体的函数体!若函数模板没有被调用则不生成任何代码也不对模板代码作任何语法检查。
b、在模板类型参数中, 实参与形参要求严格匹配,它不会进行任何的类型转换。
c、对于函数模板,我们在调用时不一定必须先进行将它实例化为一个函数也是可以的,编译器会自动的识别模板的类型。(换句话说:代码可以直接使用function, 而不需要<>)
2. 类模板
类模板的定义格式:
template <模板参数列表>
class 模板类名
{ 类的成员定义 };
1 template <class I, int a, class A> 2 class zTemplate 3 { 4 public: 5 // 函数定义 6 private: 7 // 成员定义 8 I classI; 9 A classA[a]; 10 };
1 class myI {}; 2 class myA {}; 3 4 typedef zTemplate <myI, 3, myA> myClass; 5 6 int main(int argc, char* argv[]) 7 { 8 myClass m_cMyclass; 9 return 0; 10 }