函數模板機制結論
- 編譯器并不是把函數模板處理成能狗處理任何類型的函數
- 函數模板通過具體類型產生不同的函數
- 編譯器會對函數模板進行兩次編譯,在聲明的地方對模板代碼的本身進行編譯,在調用的地方對參數替換后代碼進行編譯
- 在編譯器編譯階段,對于模板函數的使用,編譯器需要根據傳入的實參類型來推演生成對應類型的函數以供 調用。比如:當用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;}