- C++新經典:模板與泛型編程
- 王健偉編著
- 5字
- 2023-09-26 16:17:44
2.1 函數模板
2.1.1 基本范例
創建一個函數,能將兩個int類型的形參相減,將結果值返回,代碼如下。

如果是兩個float類型的形參相減呢?那么還要再寫一個函數版本,代碼如下。

可以看到,上面是兩個同名函數,屬于函數重載。
這兩個函數的區別是什么呢?除了參數類型,函數體的代碼是一樣的,重復寫這種代碼完全沒有必要,如果將來參數類型再發生改變,還得再寫一個類似的函數。那么,這種場合就是使用函數模板的最好場合。
這里,不想為每種類型都定義一個不同的函數,所以采取定義一個通用的函數模板的策略。下面看一看怎樣利用模板寫出一個適合多種參數類型求差值的函數,將剛才的兩個重載函數全部注釋,增加以下代碼,定義一個函數模板。
template <typename T> T Sub(T tv1, T tv2) { return tv1 - tv2; }
在main()主函數中添加代碼:
int subv = Sub(3, 5); cout << "subv = " << subv << endl; double subv2 = Sub(4.7 , 2.1); cout << "subv2 = " << subv2 << endl;
運行程序,查看結果:
subv = -2 subv2 = 2.6
上述就是一個函數模板的典型范例,因為函數參數的類型沒有確定,所以用T表示,這個T可以稱為模板參數,更確切地,是一個類型模板參數,因為它代表的是一個類型。
這里有一些模板的基礎知識:①模板的定義是以template關鍵字開頭;②類型模板參數T前面用typename修飾(語法就這樣規定),所以,遇到typename就應該知道其后跟的是一個類型;同時,這里的typename可以用class取代(但推薦使用typename),但這里的class并沒有“類”的意思(有些人習慣于使用typename表明對應的模板實參可以是任意類型,而使用class表明對應的模板實參必須是一個類類型);③類型模板參數T(代表一個類型)以及前面的修飾符typename都是用尖括號< >括起來的;④T可以換成任何其他標識符,對程序沒有影響,用T是一種使用習慣而已。
如果讀者對這些最基礎的模板知識仍感到陌生,從現在開始逐步去掌握,它們其實都很簡單。
如果繼續在main()主函數中添加代碼:
string a("abc"), b("def"); string addresult = Sub(a, b);
編譯一下,發現報錯,這是為什么呢?因為這里的T是string,而string類型是不支持減法操作的,所以Sub()這個函數模板里面的代碼行就是不合法的。這說明Sub()函數模板要想成功編譯,傳入的類型T必須要支持減法操作。所以,同樣一個函數模板,可能以某種方式進行調用是合法的,而換一種方式調用就不合法了。尤其值得注意的是,這種合法性,在編譯階段就可以由編譯器判斷出來,因為這些對Sub()函數模板的調用代碼就在這里擺著,編譯器有能力在編譯時就從這些調用代碼中去推斷Sub()函數模板中的模板參數T的類型。根據模板參數T的類型,編譯器就能夠判斷出這個類型是否支持減法運算。
- Python程序設計教程(第2版)
- Web應用系統開發實踐(C#)
- Android開發精要
- Python Game Programming By Example
- Access 2010數據庫基礎與應用項目式教程(第3版)
- Python數據可視化之Matplotlib與Pyecharts實戰
- INSTANT OpenNMS Starter
- JavaCAPS基礎、應用與案例
- 計算機應用基礎案例教程
- MINECRAFT編程:使用Python語言玩轉我的世界
- IBM Cognos TM1 Developer's Certification guide
- RESTful Web Clients:基于超媒體的可復用客戶端
- 進入IT企業必讀的324個Java面試題
- Java 9 with JShell
- Java RESTful Web Service實戰