函数模板机制结论
- 编译器并不是把函数模板处理成能狗处理任何类型的函数
- 函数模板通过具体类型产生不同的函数
- 编译器会对函数模板进行两次编译,在声明的地方对模板代码的本身进行编译,在调用的地方对参数替换后代码进行编译
- 在编译器编译阶段,对于模板函数的使用,编译器需要根据传入的实参类型来推演生成对应类型的函数以供 调用。比如:当用double类型使用函数模板时,编译器通过对实参类型的推演,将T确定为double类型,然 后产生一份专门处理double类型的代码,对于字符类型也是如此。
模板的局限性
-
模板不能解决所有类型
-
如果出现不能解决的类型,可以通过第三具体化来解决问题
-
template<>
返回值 函数名 <具体类型>(参数)#include<iostream>using namespace std;class Person{public:Person(string name, int age){this->m_Name = name;this->m_Age = age;}string m_Name;int m_Age;};template<class T>bool myCompare(T &a, T&b){if (a == b){return true;}return false;}//通过具体化自定义数据类型,解决上述问题//如果具体化能够优先匹配,那么就选择具体化//语法 template<>返回值 函数名<具体类型>(参数)template<> bool myCompare<Person>(Person &a, Person&b){if (a.m_Age == b.m_Age){return true;}return false;}void test01(){int a = 10;int b = 20;int ret = myCompare(a, b);cout << "ret=" << ret << endl;Person p1("Tom", 10);Person p2("Jerry", 10);int ret2 = myCompare(p1, p2);cout << "ret2=" << ret2 << endl;}int main(){test01();system("pause");return 0;}
类模板
-
与函数模板区别,可以有默认类型参数
-
函数模板可以进行自动类型推导,而类模板不行
-
成员函数 一开始不会创建出来,而是在运行时才去创建
#include<iostream>#include<string>using namespace std;template<class NameType,class AgeType=int>//类模板可以有默认的参数class Person{public:Person(NameType name, AgeType age){this->m_Name = name;this->m_Age = age;}void showPerson(){cout << "姓名:" << this->m_Name << "年龄:" << this->m_Age << endl;}NameType m_Name;AgeType m_Age;};void test01(){//自动类型推导,类模板 不支持//Person p("孙悟空", 100);//显示指定类型Person<string, int>p("孙悟空", 100);p.showPerson();}class Person1{public:void showPerson1(){cout << "Person1的调用" << endl;}};class Person2{public:void showPerson2(){cout << "Person2的调用" << endl;}};template<class T>class myClass{public:T obj;void func1(){obj.showPerson1();}void func2(){obj.showPerson2();}};//成员函数 一开始不会创建出来,而是在运行时才去创建void test02(){myClass<Person1>m;m.func1();m.func2();}int main(){//test01();test02();system("pause");return 0;}
类模板做函数的参数
-
显示的指定类型
-
参数模板化
-
整体模板化
-
查看类型名称
cout << typeid(T1).name() << endl;
#include<iostream>#include<string>using namespace std;template<class NameType, class AgeType = int>//类模板可以有默认的参数class Person{public:Person(NameType name, AgeType age){this->m_Name = name;this->m_Age = age;}void showPerson(){cout << "姓名:" << this->m_Name << "年龄:" << this->m_Age << endl;}NameType m_Name;AgeType m_Age;};//1. 指定传入类型void doWork(Person<string, int>&p){p.showPerson();}void test01(){Person<string, int >p("MT", 10);doWork(p);}//2.参数模板化template<class T1,class T2>void doWork2(Person<T1, T2>&p){//如何查看类型cout << typeid(T1).name() << endl;cout << typeid(T2).name ()<< endl;p.showPerson();}void test02(){Person<string, int>p("呆贼", 18);doWork2(p);}//3 整体模板化template<class T>void doWork3(T &p){cout << typeid(T).name() << endl;p.showPerson();}void test03(){Person<string, int>p("掠人", 18);doWork3(p);}int main(){//test01();test02();test03();system("pause");return 0;}