在《c++函式過載》一節中,為了交換不同型別的變數的值,我們通過函式過載定義了四個名字相同、引數列表不同的函式,如下所示:
//交換 int 變數的值
void
swap
(int
*a,int
*b)//交換 float 變數的值
void
swap
(float
*a,float
*b)//交換 char 變數的值
void
swap
(char
*a,char
*b)//交換 bool 變數的值
void
swap
(bool
*a,bool
*b)
這些函式雖然在呼叫時方便了一些,但從本質上說還是定義了三個功能相同、函式體相同的函式,只是資料的型別不同而已,這看起來有點浪費**,能不能把它們壓縮成乙個函式呢?
能!可以借助本節講的函式模板。
我們知道,資料的值可以通過函式引數傳遞,在函式定義時資料的值是未知的,只有等到函式呼叫時接收了實參才能確定其值。這就是值的引數化。
**在c++中,資料的型別也可以通過引數來傳遞,在函式定義時可以不指明具體的資料型別,當發生函式呼叫時,編譯器可以根據傳入的實參自動推斷資料型別。**這就是型別的引數化。
值(value)和型別(type)是資料的兩個主要特徵,它們在c++中都可以被引數化。
所謂函式模板,實際上是建立乙個通用函式,它所用到的資料的型別(包括返回值型別、形參型別、區域性變數型別)可以不具體指定,而是用乙個虛擬的型別來代替(實際上是用乙個識別符號來佔位),等發生函式呼叫時再根據傳入的實參來逆推出真正的型別。這個通用函式就稱為函式模板(function template)。
在函式模板中,資料的值和型別都被引數化了,發生函式呼叫時編譯器會根據傳入的實參來推演形參的值和型別。換個角度說,函式模板除了支援值的引數化,還支援型別的引數化。
一但定義了函式模板,就可以將型別引數用於函式定義和函式宣告了。說得直白一點,原來使用 int、float、char 等內建型別的地方,都可以用型別引數來代替。
下面我們就來實踐一下,將上面的四個swap() 函式壓縮為乙個函式模板:
#include
using
namespace std;
template
<
typename t>
void
swap
(t *a, t *b)
intmain()
執行結果:
200,
10056.93
,12.5
b, a1,
0
模板頭中包含的型別引數可以用在函式定義的各個位置,包括返回值、形參列表和函式體;本例我們在形參列表和函式體中使用了型別引數t。
型別引數的命名規則跟其他識別符號的命名規則一樣,不過使用 t、t1、t2、type 等已經成為了一種慣例。
定義了函式模板後,就可以像呼叫普通函式一樣來呼叫它們了。
在講解c++函式過載時我們還沒有學到引用(reference),為了達到交換兩個變數的值的目的只能使用指標,而現在我們已經對引用進行了深入講解,不妨趁此機會來實踐一把,使用引用重新實現 swap() 這個函式模板:
#include
using
namespace std;
template
<
typename t>
void
swap
(t &a, t &b)
intmain()
引用不但使得函式定義簡潔明瞭,也使得呼叫函式方便了很多。整體來看,引用讓編碼更加漂亮。
下面我們來總結一下定義模板函式的語法:
template
<
typename 型別引數1
,typename 型別引數2,.
..> 返回值型別 函式名(形參列表)
型別引數可以有多個,它們之間以逗號,分隔。型別引數列表以< >包圍,形式引數列表以( )包圍。
typename關鍵字也可以使用class關鍵字替代,它們沒有任何區別。c++ 早期對模板的支援並不嚴謹,沒有引入新的關鍵字,而是用 class 來指明型別引數,但是 class 關鍵字本來已經用在類的定義中了,這樣做顯得不太友好,所以後來 c++ 又引入了乙個新的關鍵字 typename,專門用來定義型別引數。不過至今仍然有很多**在使用 class 關鍵字,包括 c++ 標準庫、一些開源程式等。
本教程會交替使用 typename 和 class,旨在讓讀者在別的地方遇到它們時不會感覺陌生。更改上面的 swap() 函式,使用 class 來指明型別引數:
template
<
class
t>
void
swap
(t &a, t &b)
除了將 typename 替換為 class,其他都是一樣的。
為了加深對函式模板的理解,我們再來看乙個求三個數的最大值的例子:
#include
using
namespace std;
//宣告函式模板
template
<
typename t> t max
(t a, t b, t c)
;int
main()
//定義函式模板
template
<
typename t>
//模板頭,這裡不能有分號
t max
(t a, t b, t c)
執行結果:
1234
100↙
i_max=
10073.234
90.2
878.23↙
d_max=
878.23
344900
1000↙
g_max=
1000
函式模板也可以提前宣告,不過宣告時需要帶上模板頭,並且模板頭和函式定義(宣告)是乙個不可分割的整體,它們可以換行,但中間不能有分號。 C 函式模板使用
一.函式模板的使用 什麼是函式模板 就是建立乙個通用函式,其函式型別和形參型別不具體指定,用乙個虛擬的型別來代表,在個通用函式就稱為函式模板。函式模板的定義 格式 函式模板由三個部分組成 模板說明 函式定義 函式模板呼叫 1 模板說明 template 型別形式參數列 型別形式參數列 typenam...
c 函式模板的使用
include 函式模板的使用 define max a,b a b a b 巨集定義 using namespace std templatetype max type a,type b 整形數和實型數進行比較 char max char a,char b 字串的模板 void main exam...
C 函式模板的使用
函式模板可以用來建立乙個通用的函式,以支援多種不同形參,避免過載函式的函式體重複設計。它的最大的特點就是吧函式實用的資料型別作為引數。定義函式模板的一般形式為 template 或者template 1下面我們來試著用函式過載來定義不同型別的函式 int int int add int a,intb...