函數模板

1、簡介

在C++中,數據的類型也能夠經過參數來傳遞,在函數定義時能夠不指明具體的數據類型,當發生函數調用時,編譯器能夠根據傳入的實參自動推斷數據類型。這就是類型的參數化。ios

函數模板是一種特殊的函數,可使用不一樣的類型進行調用,對於功能相同的函數,不須要重複編寫代碼,而且函數模板與普通函數看起來很相似,區別就是類型能夠被參數化。函數

2、語法

函數模板的語法:spa

template <typename 類型參數1 , typename 類型參數2 , ...> 返回值類型  函數名(形參列表){
  //在函數體中可使用類型參數
}

類型參數能夠有多個,它們之間以逗號,分隔。類型參數列表以< >包圍,形式參數列表以( )包圍。code

typename關鍵字也可使用class關鍵字替代,它們沒有任何區別。C++ 早期對模板的支持並不嚴謹,沒有引入新的關鍵字,而是用 class 來指明類型參數,可是 class 關鍵字原本已經用在類的定義中了,這樣作顯得不太友好,因此後來 C++ 又引入了一個新的關鍵字 typename,專門用來定義類型參數。不過至今仍然有不少代碼在使用 class 關鍵字,包括 C++ 標準庫、一些開源程序等。編譯器

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;

#if 0 
//int類型數據交換
void MySwap(int& a, int& b){
	int temp = a;
	a = b;
	b = temp;
}
//double類型
void MySwap(double& a, double& b){
	double temp = a;
	a = b;
	b = temp;
}
#endif

//模板技術 類型參數化 編寫代碼能夠忽略類型
//爲了讓編譯器區分是普通函數  模板函數
template<class T1,class T2> //template<typename T>告訴編譯器 ,下面寫模板函數
void MySwap(T& a, T& b){
	T temp = a;
	a = b;
	b = temp;
}

void test01(){

	int a = 30;
	int b = 20;
	//1 自動類型推導,編譯器根據你傳的值 進行類型自動推導
	cout << "a:" << a << " b:" << b << endl;
	MySwap(a, b); 
	cout << "a:" << a << " b:" << b << endl;

	double da = 12.3;
	double db = 21.1;
	cout << "da:" << da << " db:" << db << endl;
	MySwap(da, db);
	cout << "da:" << da << " db:" << db << endl;

	//2. 顯式的指定類型
	MySwap<int>(a, b);
}

int main(void){	
	test01();
	return 0;
}

3、函數模板跟普通函數

函數模板跟普通函數同樣,也能夠被重載io

  • C++編譯器優先考慮普通函數
  • 若是函數模板能夠產生一個更好的匹配,那麼就選擇函數模板
  • 也能夠經過空模板實參列表<>限定編譯器只匹配函數模板
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;

template<class T>
int MyAdd(T a,T b){
	return a + b;
}

//普通函數能夠進行自動類型轉換
//函數模板必須嚴格類型匹配
int MyAdd(int a,int c){
	return a + c;
}

void test01(){	
	int a = 10;
	int b = 20;
	char c1 = 'a';
	char c2 = 'b';

	MyAdd<>(a,b);//限定只使用函數模板
 
	MyAdd(a,c1);//這個調用,函數模板有更好的匹配,因而調用函數模板
	MyAdd(a, b);//普通函數int MyAdd(int a,int c)已經能完美匹配,因而調用普通函數
	MyAdd(c1,b);//這個調用,函數模板有更好的匹配,因而調用函數模板
}

//函數模板被重載
template<class T>
void Print(T a){	
    
}
template<class T>
void Print(T a , T b){
    
}

int main(void)
{
	test01();	
	return 0;
}

4、函數模板機制:

  • 編譯器並非把函數模板處理成可以處理任何類型的函數
  • 函數模板經過具體類型產生不一樣的函數
  • 編譯器會對函數模板進行再次編譯,在聲明的地方對模板代碼自己進行編譯,在調用的地方對參數替換後的代碼進行編譯。
相關文章
相關標籤/搜索