C++泛型程式設計之函數模板

來源:互聯網
上載者:User

標籤:概念   重載   技術分享   span   編譯器   width   功能   stream   pre   

泛型語義

  泛型(Generic Programming),即是指具有在多種資料類型上皆可操作的含意。泛型編
程的代表作品 STL 是一種高效、泛型、可互動操作的軟體組件。
  泛型程式設計最初誕生於 C++中,目的是為了實現 C++的 STL(標準模板庫)。其語言支
持機制就是模板(Templates)。
  模板的精神其實很簡單:型別參數化(type parameterized),即,類型也是一種參數,
也是一種靜多態。 換句話說, 把一個原本特定於某個類型的演算法或類當中的類型資訊抽掉,
抽出來做成模板參數。

 

函數模板

引子:重載函數,雖然在一定程度上達到了多類型適應的目的,但是不徹底,且有二義性存在。

#include <iostream>using namespace std;void myswap(int & a, int &b)
{  int t = a;  a = b;  b = t;}
void myswap(double & a, double &b)
{  double t = a;  a = b;  b = t;}

int main()
{  long a = 2; long b = 3;  myswap(a,b); //ambiguous  cout<<a<<b<<endl;  return 0;}

 

函數模板

文法:在一個函數的參數表, 傳回型別和函數體中使用參數化類別型。

template<typename/class 型別參數 T1, typename/class 型別參數 T2,...>

特點:結構上與普通函數無異,但是在傳入參數和傳回值上做了泛化

傳回型別 函數模板名(函數參數列表){函數模板定義體}

案例:(概念比較抽象,請通過案例來觀察其特點)

關於類型,今後我們會在部落格的迭代中說明,多個不同型別參數的情況如何處理。

函數模板與普通函數的區別無非就是將函數參數高度抽象化,使其具備處理更多資料類型的能力。

特性小結

1)嚴格匹配,不存在隱式轉化。

2)先執行個體化,再調用。

3)型別參數可以省略。

4)尺有所長,寸有所短。

 

原理:

  編譯器並不是把函數模板處理成能夠處理任意類的函數; 編譯器從函數模板通過
具體類型產生不同的函數; 編譯器會對函數模板進行兩次編譯: 在聲明的地方對模板
代碼本身進行編譯, 在調用的地方對參數替換後的代碼進行編譯。

 

函數模板的應用——將快速排序演算法實現模板化

#include <iostream>#include <typeinfo>using namespace std;
template<typename T>void quickSort(T * array,int left, int right){  if(left<right)  {    int low = left; int high = right;    T pivot = array[low];    while(low<high)    {      while(array[high] >= pivot && high>low )        high--;      array[low] = array[high];      while(array[low] <= pivot&& high>low)        low++;      array[high] = array[low];
    }
  array[low] = pivot;  quickSort(array,left,low-1);  quickSort(array,low+1,right);  }}

int main(){  int array[10] = {1,3,5,7,2,4,6,8,0,9};  quickSort<int>(array,0,9);  for(auto i:array)  {    cout<<i<<endl;  }}

 

函數模板的預設參數

  函數模板,在調用時,先執行個體化為模板函數,然後再調用。當然也可以設定預設類
型的預設值。由於系統強大的自動推導能力,有時預設也沒有太大的意義。

template<typename T = int>void quickSort(T * array,int left, int right)

 

模板特化

  就是在執行個體化模板時,對特定類型的實參進行特殊處理,即執行個體化一個特殊的執行個體版本。

template<typename T> int compare( T &a, T &b)template<> int compare < const char * >( const char* &a, const char* &b)

  當以特化定義時的形參使用模板時,將調用特化版本,模板特化分為全特化和偏特
化,函數模板的特化,只能全特化;

  比如我們在比較兩個數的大小時:

#include <iostream>#include <string.h>using namespace std;
template<typename T> int compare( T &a, T &b){  if(a > b) return 1;  else if(a < b)return -1;  else return 0;}


//實參為兩個 char 指標時, 比較的是指標的大小,//而不是指標指向內容的大小, 此時就需要為該函數模板定義一個特化版本, 即特殊處理的版本:template<> int compare < const char * >( const char* &a, const char* &b){  return strcmp(a,b);}
int main(){  int a = 3; int b = 5;  cout<<compare(a,b)<<endl;  string str1 = "abc",str2 ="abc";  cout<<compare(str1,str2)<<endl;  char * p1 = "abc",*p2= "def";  cout<<compare(p1,p2)<<endl;  cout<<compare(p2,p1)<<endl;  return 0;}

關於模板特化的認識

模板特化的原因:當前函數模板的邏輯或者功能,不能滿足特定參數的需求。

模板特化的方式:將需要特化的參數提前”布置“到模板中去,提前預定模板,之後傳入需要特化的參數時便可以

優先調用經過該參數特化的模板。

 

適用情境

  函數模板,只適用於函數的參數個數相同而類型不同,且函數體相同的情況。如果
個數不同,則不能用函數模板。

 

C++泛型程式設計之函數模板

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.