当我们写交换两个变量内容的函数时虽然有函数重载但函数内容基本上都一样这样显得有些麻烦了。C 中就提供了解决该问题的方法——模板。泛型编程泛型编程指的是编写与类型无关的通用代码不指定具体数据类型等到使用时再确定其类型。泛型编程出现的意义就在于使一段代码可以适配多种不同类型的数据让我们不用重复写多个同样的代码。比如说对于不同类型数据的Swap交换函数C 中就是靠模板来实现的。## 函数模板函数模板定义的是一类函数这类函数与参数类型无关只有在特定情况下才会产生对应的函数。一个函数模板定义的方式如下template typename 类型名自定其中类型的名称我们可以自己命名通常是T。比如说我们定义函数Swap的函数模板//函数模板templatetypenameTvoidSwap(Tleft,Tright){T tmpleft;leftright;righttmp;}这就是一个函数模板了当我们显式调用它或者传参调用该函数时编译器才会根据该函数模板生成对应的函数。该过程就称为函数模板的实例化。intmain(){intx11,x22;//显式实例化//函数名后跟,内写类型//显式实例化的时候就调用该函数Swapint(x1,x2);doubled13.14,d25.12;//隐式实例化Swap(d1,d2);return0;}这是正常情况下如果我们传过去的一个是int型一个是double型那么在类型匹配上都会产生冲突第一个T匹配的是int第二个T变成了double产生了冲突这时分两种情况如果是隐式实例化此时编译器就会报错不会进入实例化阶段。如果我们已经显式实例化出了一个函数如上然后在显式实例化时就调用该函数反之报错编译器在传参时就会帮我们进行类型转换double转为int再调用这个函数。函数调用优先级如果我们已经定义了一个Swap函数假设就是int类型然后我们显式实例化出了一个int型的Swap函数那么编译器会先调用哪个函数呢voidSwap(intleft,intright){inttmpleft3;//做点区别leftright;righttmp;}//函数模板templatetypenameTvoidSwap(Tleft,Tright){T tmpleft;leftright;righttmp;}intmain(){intx11,x22;Swapint;Swap(x1,x2);coutx1 x2endl;return0;}可以看到调用的是我们自己定义的函数如果模板函数更匹配编译器则会去调用模板函数。## 类模板类模板的定义格式如下template class T比如说我们想定义不同的Stack类来存储不同类型的数据//类模板templateclassTclassStack{public:Stack(intn4):_array(newT[n]),_top(0),_capacity(n){}voidPush(Tx){_array[_top]x;}~Stack(){delete[]_array;}private:T*_array;int_top;int_capacity;};然后我们就可以生成不同的Stack类存储不同类型的数据了。intmain(){Stackints1;Stackchars2;Stackdoubles3;//这三个对象是不同的类型return0;}