1、模板python
template<模板参数表> class 类名 { //类定义体 };//注意分号不可少 templete<模板参数表>返回类型 类名<模板参数名表>:: 成员函数名1(形参表) { ......;//成员函数定义体 }
模板参数表有两种:模板类型参数和非模板类型参数。算法
2、函数模板---template关键字用于声明开始进行泛型编程-----typename关键字用于声明泛指类型----函数模板能够自动推导类型进行调用,也能够显示指定具体类型进行调用。编程
一、普通函数模板:数据结构
1 template<typename T> 2 int compare(const T& left,const T& right) 3 { 4 if(left<rigth) 5 {return -1;} 6 if(right<left) 7 {return 1;}
reurn 0; 8 } 9 10 compare<int>(1,2);//使用模板函数
二、类的成员函数模板函数
不只普通函数能够定义为模板,类的成员函数也能够定义为模板spa
class printer { public: template<typename T> void print(const T& t) { cout<<t<<endl; } } printer p; p.print<const char*>("seu");//打印seu
为了使用方便,除了直接为函数模板指定类型参数外,还可让编译器从传递给函数的实参推断参数类型,这一功能被称为模板实参推断。指针
1 compare(1,2);//推断T的类型为int 2 compare(1.0,2.0);//推断T的类型为double 3 p.print("absdsaf");//推断T的类型为const char * 4 5 int (*pf)(const int&,const int&)=compare;//推断T的类型为int; 6 //经过把函数模板赋值给一个指定类型的函数指针,让编译器根据这个指针的类型,对模板实参进行判断
三、函数模板的重载code
函数模板之间,函数模板与普通函数之间能够重载。编译器会根据调用时提供的函数参数,调用可以处理这一类型的最特殊的版本。在特殊性上,通常遵循以下顺序:orm
1 template<typename T> 2 void func(T& t) { //通用模板函数 3 cout << "In generic version template " << t << endl; 4 } 5 6 template<typename T> 7 void func(T* t) { //指针版本 8 cout << "In pointer version template "<< *t << endl; 9 } 10 11 void func(string* s) { //普通函数 12 cout << "In normal function " << *s << endl; 13 } 14 15 int i = 10; 16 func(i); //调用通用版本,其余函数或者没法实例化或者不匹配 17 func(&i); //调用指针版本,通用版本虽然也能够用,可是编译器选择最特殊的版本 18 string s = "abc"; 19 func(&s); //调用普通函数,通用版本和特殊版本虽然也均可以用,可是编译器选择最特化的版本 20 func<>(&s); //调用指针版本,经过<>告诉编译器咱们须要用template而不是普通函数
四、模板函数的特化blog
有时候函数模板并不能解决个别类型的问题,咱们必须对此进行定制,这就是函数模板的特化。函数模板的特化必须把全部的模板参数所有指定。
1 template<> 2 void func(int i) { 3 cout << "In special version for int "<< i << endl; 4 } 5 6 int i = 10; 7 func(i); //调用特化版本
3、类模板---
类模板只能显示指定类型参数,没法自动推断参数类型。声明的泛型类型参数能够出如今类模板的任意地方。类模板必须在头文件中实现,不能分开实如今不一样的文件中。
类模板适合以相同的逻辑处理不一样数据类型的数据,所以很是适合编写数据结构相关的代码。一般用来做为容器(vector)或行为(clonable)的封装。
对于一个类模板printer,只能显示的指定参数类型进行调用
printer<int> p(1);正确 printer p(1);错误