C++函數模板

1、函數模板

模板的定義:

常規定義一個函數用於交換兩個數 ,兩個數可能是 int 或者 double ,可以這麼實現

void  swap(int &x, int &y);
void swap(double &x, double &y);

但是如果種類比較多的話,就需要寫很多個參數,而這幾個函數的樣式基本一樣,從中總結出共性,如下結構

template <typename T>
void swap(T &x ,T &y){
    T temp ;
    temp =x;
    x=y;
    y=temp;
}

以上也就是函數模板的形式,要注意的是 模板的聲明需要將模板的頭一起帶上,如下:

template <typename T>
void swap(T &x, T &y);

模板的使用:

定義了一個如上的模板,要使用它的時候 ,以下是main函數中

int a = 1;
int b = 2;
double c = 3.0;
double d = 4.0;

my_swap(a, b);
my_swap(c, d);

cout << " a = " << a << "  b = " << b << endl;
cout << " c = " << c << "  d = " << d << endl;

image

從結果看確實實現了功能,這可比使用函數重載好用多了

  • 需要注意的是在std中也定義一個 swap ,直接使用的話會用衝突問題,所以這裏我改了個名字

結合模板和重載 :

模板和重載各有特色,如果能結合兩個一起使用,效果更好

  • 觀察結果可以發現,模板用於函數結構完全一樣的地方,僅僅是類型上的不同,使用泛型可以根據使用條件,自動生成函數。這和同名函數重載查找匹配函數很像。但是如果參數數目不一樣的話,就沒有辦法使用模板結構。

以下結合兩種使用:

template <typename T> 
void my_swap(T &x, T &y);

template <typename T> 
void my_swap(T &x, T &y, int n);
  • 模板中並非全部的類型都是泛型,也可以有普通的數據類型

模板的侷限性

  • 雖然模板中的是泛型,但是有些類型可能是不能使用的,比如使用泛型進行大小比較,但是具體調用的時候,泛型是用 結構體帶入,可能就會出問題。這只是一個例子,所以使用結果體還是需要根據需要做好判斷。

具體化

  • 具體化 分成3重種 :隱式實例化、顯示實例化、顯示具體化

    1. 隱式實例化: 在上述使用的函數模板中,並沒有給出實際的函數,只是給定生成一個函數的規則,編譯器在編譯期間根據實際情況,實例化生成一個函數調用,但是我們沒看見,這是隱式實例化 。
    2. 顯示實例化:在使用模板中,我們希望先按照規則生成一個模板來使用。
tempalte void my_swap<int>(int , int );

不過由於是模板的實例化,在這之前,必須先有函數模板的存在,否則會出現如下錯誤
image

  1. 顯示具體化
template <> void my_swap<job>(job &x, job &y);
  • 顯示具體化和顯示實例化看起來非常像,但是存在的理由是什麼呢。目前實際中我還沒有看到,只能猜測,如果一個用結構實現的my_swap(job &, job &);結構和普通的模板一樣,顯然不能直接使用模板實例化使用,顯示具體化的優先級更高,定義了顯示具體化後可以在模板實例化之前調用正確的顯示具體化函數。

  • 同一個函數名,可以給同時存在,這幾種形式,普通非模板函數、模板函數、顯示具體化模板函數 、其他重載函數。

  • 調用優先級: 普通函數 >顯示具體化模板 >普通模板函數
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章