模板就好像一个模子,我们知道古时候会用到各种各样的模子来制作东西,而这种模子就好像是我们的模板一样。模板是模板和它所产生的类或者函数是不一样的,我们产生的类或者函数用的可不是模板 模板分为:函数模板 和 类模板
函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生函数的特定类型
template <class T>//class可以用typename替代,但是不能使用struct。后面只能跟一个函数 void swap(T& p, T& q) { T tmp = p; p = q; q = tmp; } int main() { int a=1,b=2; swap(a,b); }
这个就是一个函数模板的典型案例,我们调用它时,调用的函数模板产生的函数,不是模板的本身。函数模板的类型一般是编译器根据实参传给形参推演出来的,但是有的时候还是需要我们自己去显示实例化的,比如:test<int>(10);
模板参数也是可以给缺省参数的哦 :
template <class T = int> void swap(T& p, T& q) { T tmp = p; p = q; q = tmp; } int main() { int a=1,b=2; swap(a,b); }
模板也是可以声明和定义分离的,但不支持把他们放到两个文件里面,这样会出现链接错误,因为那些放在.c文件的定义,链接是找不到这些函数模板调用的地址(毕竟你不知道这个模板里面的T的类型,编译器自然就不会把这一部分写进符号表里面),除非你去显示实例化指定:
1. template; 2. void swap<int>(int& p,int& q);
template <class T> void swap(T& p, T& q); template <class T> void swap(T& p, T& q) { T tmp = p; p = q; q = tmp; }
template <class T>//模板参数可以有多个 class date { public: date(int a = 1); private: int _hour; int* _a; }; template <class T> date<T>::date(int a) { _hour = a; _a = new T[10]; }
大家觉得这样的代码对嘛:
template <class T> void swap(T& p, T& q) { T tmp = p; p = q; q = tmp; } int main() { int a = 1; double b = 2.0; swap(a,b); }
这样肯定是不行的,编译器在判断T的时候就会矛盾,不知道这里的T应该是int还是double那可以怎么解决呢?
1. swap<int>(a,b); 2. swap<double>(a,b);
其实可以向我们上面这样显示实例化,实际上模板类也是要自己显示实例化才能使用的,除非你自己写的有缺省参数
如果现在有一个函数,还有一个函数模板,模板除了参数是模板参数以外其他都和我们得函数相同,大家觉得这个函数和这个函数模板可以同时存在嘛?存在时调用又是先用哪一个呢
这两个肯定是可以同时存在的,他们完全两种不同的东西,调用的时候自然也是调用我们已经写好的函数,编译器也会图方便去调用更便捷那个