作用:提高程序可复用性,程序编译时自动生成相应函数
函数模板和类模板中的类型参数表中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;
}
}
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;
}
原文:https://www.cnblogs.com/DreamEagle/p/12632072.html