第七章 2.泛型编程(模板)
程序员文章站
2022-03-20 15:45:26
[TOC] 作用:提高程序可复用性,程序编译时自动生成相应函数 函数模板和类模板中的类型参数表中 和`typename`可相互替换 函数模板 2. 格式 3. 匹配顺序 参数完全匹配的普通函数 参数完全匹配的模板函数(匹配模板函数时,不会进行自动类型转换) 实参经过自动类型转换 后匹配的普通函数 上 ......
目录
作用:提高程序可复用性,程序编译时自动生成相应函数
函数模板和类模板中的类型参数表中class
和typename
可相互替换
函数模板
-
格式
template<class t1,class t2,...> 返回值类型 模板名(参数表){ 函数体 }
-
匹配顺序
- 参数完全匹配的普通函数
- 参数完全匹配的模板函数(匹配模板函数时,不会进行自动类型转换)
- 实参经过自动类型转换 后匹配的普通函数
- 上述匹配均不存在则报错
-
可通过
模板函数名<类型>
不通过参数实例化 -
模板函数也可以重载,只要形参表或类型参数表不同即可
-
支持函数指针类型
#include<iostream> using namespace std; template<class t,class pred> void map(t s,t e,t x,pred op){ for(;s!=e;s++,x++) *x=op(*s); } double square(double x){return x*x;} int cube(int x){return x*x*x;} template<class t> void output(t &arr){ for(int i=0;i<(sizeof(arr)/sizeof(*arr));++i) cout<<arr[i]<<" "; cout<<endl; } int main(){ int a[5]={1,2,3,4,5},b[5]; double d[5]={1.1,2.2,3.3,4.4,5.5},c[5]; map(a,a+5,b,square); output(b); map(a,a+5,b,cube); output(b); map(d,d+5,c,square); output(c); return 0; }
类模板
-
定义方式:
template<class t1,class t2,...> class classname{ member function; member variable; returntype func(parameter table); } //在类外定义成员函数 template<class t1,class t2,...> returntype classname<t1,t2,...>::func(parameter table){ ... } //通过类模板定义对象 classname<t1,t2,...> obj; //类模板的类型参数表可以包含非类型参数 template<class t,int size> class count{ public: t arr[size]; void output(){ for(int i=0;i<size;++i) cout<<arr[i]<<endl; } } count<double,50> test;
-
在类模板内定义函数模板
class test{ public: template<class t2> void func(t2 a){ cout<<a<<endl; } }; int main(){ test<int> a; a.func("test"); return 0; }
-
编译器由类模板生成类的过程称为类的实例化,生成的类称为模板类
-
同一类模板生成的不同模板类不兼容(即两个独立不同的类型)
类模板与派生
-
类模板从类模板派生
-
类模板从模板类派生
-
类模板从普通类派生
-
普通类从模板类派生
template<class t1,class t2> class a{ t1 v1; t2 v2; } //类模板从类模板中派生 template<class t1,class t2> class b:public a<t2,t1>{ //a模板实例化顺序不一定相同 t1 v3; t2 v4; } //类模板从模板类派生 template<class t> class b:public a<int,double>{} //类模板从普通类中派生 class c{int a;} template<class t> class b:public c{ t val; } //普通类从模板类中派生 class d:public a<int,double>{ int a;}
类模板与友元
-
函数、类、类成员函数作为类模板友元
void func1(){} class a{ int a; public: void func(){} } template<class t> class b{ t a; public: friend void func1(); //友元函数 friend class a; //友元类 friend void a::func(); //类成员函数作为友元类 }
-
函数模板作为类模板友元
template<typename t1,typename t2> class pair{ t1 key; t2 value; public: pair(t1 k,t2 v):key(k),value(v){} //函数模板作为类模板友元 template<class t3,class t4> //不能写t1、t2,否则可能报错 friend ostream& operator<< (ostream &out,const pair<t3,t4> &p); }; template<class t1,class t2> ostream& operator<< (ostream& out,const pair<t1,t2> &p){ return out<<"("<<p.key<<","<<p.value<<")"<<endl; }
-
函数模板作为类的友元
class a{ int v; public: a(int n):v(n){} template<class t> friend void print(const t& p); } template<class t> void print(const t& p){cout<<p.v;} int main(){ a a(10); print(a); return 0; }
-
类模板作为类模板友元
template<class t> class a{ t v; public: a(int n):v(n){} template<class t2> //不能写成t,可能报错 friend class b; } template<class t> class b{ public: void func(){ a<int> o(10); cout<<o.v<<endl; } }
类模板中的static成员
-
统一类模板的不同类型的实例static相互独立,相同类型示例共用
class a{ static int count; public: void printcnt(){ cout<<count<<endl; } a(){count++;} ~a(){count--;} a(a&){count++;} }; template<> int a<int>::count=0; //类模板中static变量声明方式 template<> int a<double>::count=0; int main(){ a<int> a,c; a.printcnt(); //2 a<double> b; b.printcnt(); //1 return 0; }