//第二十三模板 3具体化函数模板 //具体化函数模板, 顾名思义, 即具体化了函数参数和功能的模板 //1 函数模板不能重载 /*#include <iostream> using namespace std; template <class T> void Swap(T &a, T &b); struct people { char name[10]; int age; }; void show(people &p); int main() { int i=10,j=20; cout<<"初始值i="<<i<<", j="<<j<<endl; Swap(i,j); cout<<"执行Swap函数后i="<<i<<", j="<<j<<endl; people Jack={"Jack",44}; people Mick={"Mick",22}; cout<<"交换前:"<<endl; show(Jack); show(Mick); Swap(Jack,Mick); cout<<"交换后:"<<endl; show(Jack); show(Mick); return 0; } template<class T> void Swap(T &a, T &b) { T temp; temp = a; a = b; b = temp; } void show(people&p) { cout<<p.name<<"的年龄是"<<p.age<<endl; }*/ //不过假如我们只交换年龄age,而不交换姓名name的话,那么定义的Swap模板就不适合了,我们需要再增加一个只交换name成员的模板函数,但是我们不能对Swap模板函数进行重载,因为新的Swap()函数的两个参数保持不变,仍是T &a,和T &b //2 具体化函数模板解决重载问题 //C++为模板提供了一个具体化函数定义的特性,又称显式具体化, //例如,我们可以为Swap()函数的两个不具体参数T &a和T &b定义两个具体的参数 //我们首先看如何声明和定义这样的函数 //tempalte<>void Swap<people>(people&p1,people&p2); //该段语句告诉编译器不要使用Swap模板函数,而要使用具体化的Swap函数来创建一个Swap函数,尖括号中的people指明了具体化的类型,而小括号中的"people&p1,people&p2"则使用该类型声明了两个参数 /*#include <iostream> using namespace std; template <class T> void Swap(T &a, T &b); struct people { char name[10]; int age; }; template<>void Swap<people>(people&p1,people&p2); //该模板相当于创建一个 void Swap(people&a, people&b); void show(people &p); int main() { int i=10,j=20; cout<<"初始值i="<<i<<", j="<<j<<endl; Swap(i,j); cout<<"执行Swap函数后i="<<i<<", j="<<j<<endl; people Jack={"Jack",44}; people Mick={"Mick",22}; cout<<"交换前:"<<endl; show(Jack); show(Mick); Swap(Jack,Mick); cout<<"交换后:"<<endl; show(Jack); show(Mick); return 0; } template<class T> void Swap(T &a, T &b) { T temp; temp = a; a = b; b = temp; } template<>void Swap<people>(people&p1,people&p2) //void Swap(people&a, people&b) { int Age; Age = p1.age; p1.age = p2.age; p2.age = Age; } void show(people&p) { cout<<p.name<<"的年龄是"<<p.age<<endl; }*/ // 3 具体化函数模板与实例化模板函数 //注意下面两行语句的区别 //template<>void Swap<people>(people&p1,people&p2); //template void Swpa<people>(people&p1,people&p2); //第一行声明了一个具体化函数模板,第二行则显示地声明了一个实化模板函数 //显示实例化模板的使用方法,并说明了该模板只是确定函数的参数,而不会修改函数功能 /*#include <iostream> using namespace std; template<class T> void show(T a){ cout<<"void show(T a):";cout<<a<<endl;} template void show<char>(char&); //区分一下模板实例和模板定义的区别 //模板实例即是由模板生成的成品 //void show(int a){ cout<<a<<endl;} //这是一个完整的函数,编译器根据我们定义的模板方案最终也会生成这样的函数,我们把这个由模板生成的函数叫做模板实例 //模板定义在编译前不会生成这样的函数,它只是一个用于生成该函数方案 //template<class T> //void show(T a){cout<<a<<endl; } //显示实例化,函数参数具体为int //template void show<int>(int); //void show(T a){cout<<a<<endl;} //参数是不具体的,但是功能是具体的 //void show(int a){cout<<a<<endl; }//参数具体,功能具体 int main() { show(5); return 0; }*/ //总结: //1 具体化函数模板可帮助我们实现对具有相同参数个数的函数模板的重载,并且它的执行优先级高于具体化的函数模板 //2 显示实例化模板则强制生成一个我们设置好参数类型的函数,这在我们预料到会调用该参数类型的函数时可提高手动编译和连接的效率,由于该模板可有可无,不是必须存在的,因此我们只需了解即可以