目录
分类
一、普通函数,参数和返回值是模板类的实例化版本(只支持AA模板类的某一个具体化类)
1)代码
2)分析
3)运行结果
二、函数模板,参数和返回值是某种模板类(只支持AA模板类)
1)代码
2)分析
3)运行结果
三、函数模板,参数和返回值是任意类型(支持普通类和模板类和其他类型)
一)支持模板类的任意具体化类(多个)
1)代码
2)分析
3)运行结果
二)支持普通类
1)代码
2)分析
3)运行结果
三)支持函数
1)传入类
2)传入函数指针
分类
模板类用于函数的参数和返回值,有三种形式
1)普通函数,参数和返回值是模板类的实例化版本
2)函数模板,参数和返回值是某种模板类
3)函数模板,参数和返回值是任意类型(支持普通类和模板类和其他类型)
一、普通函数,参数和返回值是模板类的实例化版本(只支持AA模板类的某一个具体化类)
1)代码
#include<iostream>
using namespace std;
template<class T1,class T2>
class AA
{
public:
T1 m_x;
T2 m_y;
AA(const T1 x,const T2 y):m_x(x),m_y(y){}
void show()const{cout<<"show() x="<<m_x<<",y="<<m_y<<endl;}
};
//采用普通函数,参数和返回值是模板类的实例化版本
//AA<int,string>是一个具体的类型,可以直接传值也可以直接传引用
AA<int,string> func(AA<int,string>&aa)
{
aa.show();
cout<<"调用了func(AA<int,string>&aa)函数"<<endl;
return aa;
}
int main()
{
AA<int,string>aa(3,"我是一只小猫咪。");
func(aa);
return 0;
}
2)分析
①//AA<int,string>是一个具体的类型,可以直接传值也可以直接传引用
②AA<int,string> func(AA<int,string>&aa)是一个普通的全局函数
③函数传入的参数是一个具体的类
3)运行结果
二、函数模板,参数和返回值是某种模板类(只支持AA模板类)
1)代码
#include<iostream>
using namespace std;
template<class T1,class T2>
class AA
{
public:
T1 m_x;
T2 m_y;
AA(const T1 x,const T2 y):m_x(x),m_y(y){}
void show()const{cout<<"show() x="<<m_x<<",y="<<m_y<<endl;}
};
//采用普通函数,参数和返回值是模板类的实例化版本
//AA<int,string>是一个具体的类型,可以直接传值也可以直接传引用
AA<int,string> func(AA<int,string>&aa)
{
aa.show();
cout<<"调用了func(AA<int,string>&aa)函数"<<endl;
return aa;
}
//采用函数模板,参数和返回值是某种模板类
template<typename T1,typename T2>
AA<T1,T2> func(AA<T1,T2>&aa)
{
aa.show();
cout<<"调用了func(AA<T1,T2>&aa)函数"<<endl;
return aa;
}
int main()
{
AA<char,string>aa(3,"我是一只小猫咪。");
func(aa);
return 0;
}
2)分析
①main函数中AA的参数类型改为char,此时普通函数已经不能再适用
//采用普通函数,参数和返回值是模板类的实例化版本
AA<int,string> func(AA<int,string>&aa)
②故需要重写出一个模板函数,因为类模板的通用类型参数是有T1和T2,所以模板函数也有两个通用类型参数。(只支持AA模板类)
template<typename T1,typename T2>
AA<T1,T2> func(AA<T1,T2>&aa)
{
aa.show();
cout<<"调用了func(AA<T1,T2>&aa)函数"<<endl;
return aa;
}
③在函数中,如果想发挥类模板的通用性,必须结合函数模板
④这个模板函数没有发挥出模板函数的通用性,下面给出更通用的模板函数即(支持支持普通类和模板类和其他类型
3)运行结果
注:如果此时char改为int型,则会调用普通函数((一)当中的函数)
三、函数模板,参数和返回值是任意类型(支持普通类和模板类和其他类型)
一)支持模板类的任意具体化类(多个)
1)代码
#include<iostream>
using namespace std;
template<class T1,class T2>
class AA
{
public:
T1 m_x;
T2 m_y;
AA(const T1 x,const T2 y):m_x(x),m_y(y){}
void show()const{cout<<"show() x="<<m_x<<",y="<<m_y<<endl;}
};
//采用普通函数,参数和返回值是模板类的实例化版本
//AA<int,string>是一个具体的类型,可以直接传值也可以直接传引用
AA<int,string> func(AA<int,string>&aa)
{
aa.show();
cout<<"调用了func(AA<int,string>&aa)函数"<<endl;
return aa;
}
//采用函数模板,参数和返回值是某种模板类
//template<typename T1,typename T2>
//AA<T1,T2> func(AA<T1,T2>&aa)
//{
// aa.show();
// cout<<"调用了func(AA<T1,T2>&aa)函数"<<endl;
// return aa;
//}
//采用函数模板,参数和返回值是任意类型(支持普通类和模板类和其他类型)
template<typename T>
T func(T&aa)
{
aa.show();
cout<<"调用了func(AA<T>&aa)函数"<<endl;
return aa;
}
int main()
{
AA<char,string>aa('3',"我是一只小猫咪。");
func(aa);
return 0;
}
2)分析
①注释掉//采用函数模板,参数和返回值是某种模板类(只支持AA模板类)
//template<typename T1,typename T2>
//AA<T1,T2> func(AA<T1,T2>&aa)
因为程序会调用该较为具体化的版本
②重写模板函数
//采用函数模板,参数和返回值是任意类型(支持普通类和模板类和其他类型)
template<typename T>
T func(T&aa)
{
aa.show();
cout<<"调用了func(AA<T>&aa)函数"<<endl;
return aa;
}
3)运行结果
二)支持普通类
1)代码
#include<iostream>
using namespace std;
template<class T1,class T2>
class AA
{
public:
T1 m_x;
T2 m_y;
AA(const T1 x,const T2 y):m_x(x),m_y(y){}
void show()const{cout<<"show() x="<<m_x<<",y="<<m_y<<endl;}
};
//采用普通函数,参数和返回值是模板类的实例化版本
//AA<int,string>是一个具体的类型,可以直接传值也可以直接传引用
AA<int,string> func(AA<int,string>&aa)
{
aa.show();
cout<<"调用了func(AA<int,string>&aa)函数"<<endl;
return aa;
}
//新增普通类
class BB
{
public:
void show(){cout<<"调用了BB的show()函数。"<<endl;}
};
//采用函数模板,参数和返回值是某种模板类
template<typename T1,typename T2>
AA<T1,T2> func(AA<T1,T2>&aa)
{
aa.show();
cout<<"调用了func(AA<T1,T2>&aa)函数"<<endl;
return aa;
}
//采用函数模板,参数和返回值是任意类型(支持普通类和模板类和其他类型)
template<typename T>
T func(T&aa)
{
aa.show();
cout<<"调用了func(AA<T>&aa)函数"<<endl;
return aa;
}
int main()
{
AA<char,string>aa('3',"我是一只小猫咪。");
BB bb;
func(bb);//类
return 0;
}
2)分析
①新增一个普通类BB
class BB
{
public:
void show(){cout<<"调用了BB的show()函数。"<<endl;}
};
②在函数模板中,只要类对象支持函数模板体
aa.show();
则该函数模板支持此对象
③传入的是普通类
func(bb);//类
3)运行结果
三)支持函数
重写一个代码,和上面的不同
1)传入类
①)代码
#include<iostream>
using namespace std;
void show()
{
cout<<"调用了show()函数。"<<endl;
}
//普通类BB
class BB
{
public:
void operator()(){//重载()也叫仿生函数
cout<<"调用了BB类的仿函数。"<<endl;
}
};
//函数模板,参数和返回类型是任意类型(支持普通类和模板类,还可以支持其他)
template<typename T>
void func(T tt)
{
tt();
}
int main()
{
BB bb;
func(bb);//传入类
return 0;
}
②)分析
①传入的是类
func(bb);//传入类
③)运行结果
2)传入函数指针
①)代码
#include<iostream>
using namespace std;
void show()
{
cout<<"调用了show()函数。"<<endl;
}
//普通类BB
class BB
{
public:
void operator()(){//重载()也叫仿生函数
cout<<"调用了BB类的仿函数。"<<endl;
}
};
//函数模板,参数和返回类型是任意类型(支持普通类和模板类,还可以支持其他)
template<typename T>
void func(T tt)
{
tt();
}
int main()
{
BB bb;
func(show);//传入show函数的指针
return 0;
}
②)分析
①函数模板,不管传入的是什么类型,只要适应函数体内的代码tt();即可
②show()是一个全局函数,传入的是函数指针
func(show);//传入show函数的指针
③)运行结果