C++ 函數模板用法


泛型編程概念:不考慮具體數據類型的編程方式;

函數模板:

1.提供一種特殊的函數可用不同類型進行調用;

2.與普通函數很相似,區別是類型可被參數化;

template <typename T>   //template關鍵字用於聲明開始進行泛型編程
void Swap(T &a, T &b)   //typename關鍵字用於聲明泛指類型
{
     T tmp = a;
        a = b;
        b = tmp;       
}

函數模板的應用:

1.自動類型推導調用;

2.具體類型顯示調用;

int a = 3;
int b = 4;
Swap(a,b);                    //自動類型推導調用

float fa = 5.5;
float fb = 8.8;
Swap<float>(fa, fb)          //具體類型顯示調用,用float替換參數類型T

使用演示:

#include <iostream>

template <typename T>                           //交換變量
void Swap(T& a, T& b)
{
	T t;
	t = a;
	a = b;
	b = t;
}

template <typename T>                       //將數組內容從小到大排序
void SelectMin(T array[], int size)
{
	for (int i = 0; i < size; i++)
	{
		T Min = array[i];
		int Index = 1;
		for (int j = i + 1; j < size; j++)
		{
			if (Min > array[j])
			{
				Min = array[j];
				Index = j;
				Swap(array[i], array[Index]);
			}
		}
		
	}
}


int main()
{
	int a = 3;
	int b = 8;
	Swap(a, b);       //自動類型推導
	std::cout << "a = " << a << std::endl;
	std::cout << "b = " << b << std::endl;

	float fa = 3.4;
	float fb = 8;
	Swap<float>(fa, fb); //具體類型顯示調用
	std::cout << "fa = " << fa << std::endl;
	std::cout << "fb = " << fb << std::endl;

	char ca = 'a';
	char cb = 'b';
	Swap(ca, cb);
	std::cout << "ca = " << ca << std::endl;
	std::cout << "cb = " << cb << std::endl;

	int array[] = {4, 3, 1, 2, 45};
	SelectMin(array, 5);
	for (int i = 0; i < 5; i++)
	{
		std::cout << "i = " << array[i] << std::endl;
	}

	char array2[] = { 'a', 'f', 'e', 'c', 'b' };
	SelectMin(array2, 5);
	for (int i = 0; i < 5; i++)
	{
		std::cout << "i = " << array2[i] << std::endl;
	}
	return 0;
}

  

函數模板的深入理解:

-- 編譯器並不會把函數模板處理成能夠處理任意類型的函數;

--編譯器從函數模板通過具體類型產生不同的函數;

--編譯器會對函數模板進行兩次編譯;

  --在聲明的地方對模板代碼本身進行編譯

  --在調用的地方對參數替換后的代碼進行編譯

 

當函數模板遇到函數重載:

--C++編譯器優先考慮普通函數;

--如果函數模板可以產生一個更好的匹配,那么選擇模板;

--通過空模板實參列表的語法限定編譯器只通過模板匹配;

注意事項:

--函數模板不允許自動類型轉化;

--普通函數能夠進行類型轉化;

int Max(int a, int b)              //普通函數
{
   return a > b ? a : b;  
}

template <typename T>    //模板函數
T Max(T a, T b)
{
   return  a > b ? a : b;  
}

int main()
{
   int a = 4;
   int b = 8;
   Max(a,b);        //調用普通函數
   Max<>(a,b);  //空模板實參列表,只能調用函數模板
 
   float fa = 5.5;
   float fb = 8.8;
   Max(fa,fb);    //調用普通函數會進行類型轉換,通過函數模板會產生一個更好的匹配
 
   Max('a',100);//返回結果是調用普通函數a的ASCII碼,因為‘a’是字符型,100是整形,與函數模板不匹配
return 0; }

 

函數模板可以定義多個類型的參數:

template <typename T1, typename T2, typename RT>
RT Add(T1 a, T2 b)         //RT作為返回類型
{
     return static_cast<RT>(a+b)
}

cout<<Add<char, float, double>('a', 100)<<endl;
當聲明的類型參數作為返回值類型,無法推導出返回值類型!
即Add('a', 100)這樣自動推導調用編譯器會報錯;

不完美處理方案:
template <typename RT, typename T1, typename T2>
RT Add(T1 a, T2 b)         //RT作為返回類型
{
     return static_cast<RT>(a+b)
}

cout<<Add<double>('a', 100)<<endl;   //將返回類型放在第一個參數,只顯示的列出返回值類型,其它2個參數編譯器自動推導

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM