C++:函式模板詳解
阿新 • • 發佈:2020-12-16
C++:函式模板詳解
一、函式模板
#include <iostream> using namespace std; // 利用模板實現通用交換函式 // T代表通用的資料型別,告訴編譯器下面緊跟著的函數出現T不要報錯。 template <class T> void userSwap(T& var01, T& var02) { T tmp = var01; var01 = var02; var02 = tmp; } /* 模板函式呼叫方式: 1、自動型別推導:實參列表中,T對應資料型別須一致; 2、顯式指定T實參型別 */ int main() { int a = 100; int b = 200; 1、自動型別推導:實參列表中,T對應資料型別須一致; userSwap(a, b); // 實參a、b均為int型資料,函式可自行推匯出T為int型資料型別。 cout<<"a = "<<a<<endl; // a = 200 cout<<"b = "<<b<<endl; // b = 100 float c = 1.414; float d = 1.732; // 2、顯式指定型別 userSwap<float>(c, d); // 顯式指定T為float資料型別,此時實參c、d亦須是float資料型別 cout<<"c = "<<c<<endl; // c = 1.732 cout<<"d = "<<d<<endl; // d = 1.414 return 0; }
二、模板不能單獨使用,須指定T才可以使用。
#include <iostream>
using namespace std;
template <class T>
void func(){}
int main()
{
// func(); // 模板不能單獨使用,須指定T才可以使用。
func<int>(); // 指定T的型別為int,可以正常呼叫
return 0;
}
三、模板函式和普通函式的呼叫規則
1、若函式模板與普通函式都可以呼叫,優先呼叫普通函式
2、若要強制呼叫函式模板,可使用空模板函式列表
3、函式模板可發生函式過載
4、若函式模板可產生更好的匹配,則優先呼叫函式模板
#include <iostream> #include <string> using namespace std; template <class TYPE> void userPrint(TYPE var01, TYPE var02) { cout<<"函式userPrint(TYPE var01, TYPE var02)呼叫"<<endl; } // 模板函式發生過載 template <class TYPE> void userPrint(TYPE var01, TYPE var02, TYPE var03) { cout<<"函式userPrint(TYPE var01, TYPE var02, TYPE var03)呼叫"<<endl; } void userPrint(int var01, int var02) { cout<<"普通函式userPrint(int var01, int var02)呼叫"<<endl; } int main() { int a = 10; int b = 20; // a、若函式模板與普通函式都可以呼叫,優先呼叫普通函式 userPrint(a, b); // 呼叫普通函式userPrint(int var01, int var02) // b、若要強制呼叫函式模板,可使用空模板函式列表 userPrint<>(a, b); // 呼叫普通函式userPrint(TYPE var01, TYPE var02) // c、函式模板可發生函式過載 userPrint(a, b, 10); // // 呼叫普通函式userPrint(TYPE var01, TYPE var02, TYPE var03) // 4、若函式模板可產生更好的匹配,則優先呼叫函式模板 char c = 'c'; char d = 'd'; userPrint(c, d); // // 呼叫普通函式userPrint(TYPE var01, TYPE var02) return 0; }
四、函式模板實現機制
1、編譯器並非將函式模板處理成可處理任何型別資料的函式;
2、函式模板通過具體的資料型別產生不同的函式,新生成的函式稱為模板函式;
3、編譯器會對函式模板進行兩次編譯。宣告時對模板自身程式碼進行一次編譯;在呼叫時對引數替換後的程式碼再進行一次編譯。
五、函式模板的侷限性
1、函式模板並不能對任意的資料型別進行操作(如自定義資料型別);
2、可利用具體化技術,實現對自定義資料型別提供特殊模板。template<> bool myCompare(const Person& a, const Person& b)
#include <iostream>
#include <string>
using namespace std;
class Person
{
public:
string name;
int age;
public:
explicit Person(string name, int age)
{
this->name = name;
this->age = age;
}
};
// 不能對自定義的資料型別資料進行操作
template <class TYPE>
bool myCompare(const TYPE& a, const TYPE& b)
{
return a == b;
}
// 利用具體化技術,實現對自定義資料型別提供特殊模板。
template<> bool myCompare(const Person& a, const Person& b)
{
return (a.name == b.name && a.age == b.age);
}
int main()
{
int a = 10;
int b = 20;
if(myCompare(a, b))
{
cout<<"a == b"<<endl;
}
else{
cout<<"a != b"<<endl;
}
Person p1("Lisi", 20);
Person p2("Lisi", 20);
if(myCompare(p1, p2))
{
cout<<"p1 == p2"<<endl;
}
else{
cout<<"p1 != p2"<<endl;
}
return 0;
}