1. 程式人生 > 其它 >C++:函式模板詳解

C++:函式模板詳解

技術標籤:C++入門c++

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;
}