標籤: c++ template
對於c++模板,之前很少使用,這裡整理下,以備後忘。
先來看下面2個加法函式:
上面的2個函式,雖然它們的返回值和引數型別不一致,但函式名和函式體完全一致。如果能提煉出乙個通用函式,並適用不同的資料型別,則會大大提高**的可重用性。c++的模板就可以解決這種問題。int
sum(int a, int b)
double
sum(double a, double b)
模板是c++支援引數化多型的工具,它可以實現型別引數化,即使類中的資料成員或成員函式的引數、返回值取得任意型別。模板是一種對型別進行引數化的工具,能減少程式設計師編寫型別無關的**。
c++的模板可分為函式模板和類模板,通過函式模板具體化的函式稱為模板函式,通過類模板具體化的類稱為模板類。
所謂函式模板實際上是建立乙個通用函式,其涵涵素型別額形參型別不具體指定,用乙個虛擬的型別來代表,這個通用函式就稱為函式模板
定義乙個函式模板的格式並不複雜,形式如下:
其中,template是宣告模板的關鍵字;typename用來標識的形參名用來表示乙個虛擬型別,當使用函式模板時,會將其具體化為具體的型別,typename關鍵字也可以用class替換。template ...>
返回值 函式名(函式引數列表)
下面,對剛開始的2個函式,使用函式模板定義並呼叫
它是如何兼用int和double型別的呢:#include
template
t sum(t a, t b)
int main()
上面編寫的t sum(t a, t b)
,只是乙個「函式模板」,使用它是需要先例項化為乙個「模板函式」(如int sum(int,int)
)。編譯器在編譯階段,為每個呼叫次模板的**生成了乙個函式。
模板的形參有型別形參和非型別形參:
- 型別形參:由關鍵字typename加說明符構成,表示一種未知的型別,上面例子中的形參都是型別形參。
- 非型別形參:非型別形參是內建型別形參,如template
,其中int m
是模板非型別形參。
a)非型別形參只可以是整型、指標或引用;
b)繫結到整形(非型別引數)的實參必須是乙個常量表示式,繫結到指標或引用(非型別引數)的實參必須具有靜態的生存期(比如全域性變數),即在編譯階段就能確定其值。
函式模板的過載也稱之為函式的特例化。
看下面乙個例子:
輸出結果是:template
void fun(t a)
template fun: a
int fun: 2
相應的,類模板是用來生成類的通用模板。
定義乙個類模板的格式如下:
編譯器不能為類模板推斷模板引數型別,使用時必須顯式的提供模板實參。同樣的,其形參可以時型別形參,也可以是非型別形參。template ...
};
下面是乙個類模板定義的例子
上面的例子中,類模板的成員函式是定義在內部的,也可以定義在外部。定義在類模板之外的成員函式必須以關鍵字templatet>
class compare
t max()
t min()
private:
t m_data1;
t m_data2;
};
template
開始,後接類模板引數列表。
如上面的max
在外部定義時:
與函式模板類似,它僅在編譯時根據例項化本模板時傳遞的實參來生成具體的類**!若類模板沒有被例項化也沒有被呼叫,那編譯器不會為本模板生成任何**也不對模板**作任何語法檢查。template t>
t compare::max()
對類模板的靜態資料成員,有如下:
可通過下面例子進行驗證
在此前的例子中都是類模板中有成員函式,而對於普通類來說,也可以有成員函式模板,如以下**所示:template
class a
void disp()
普通類中的成員函式模板可以在類中當場實現,也可以在類外單獨實現。在類外實現時,由於類不是模板,無需在類名後增加模板實參列表。struct normal_class
template
t get();
};
template
t normal_class::get()
類模板的成員函式還可以有額外的模板引數,如:
1.在類模板中允許再嵌入模板,因此類模板的巢狀類也是乙個模板,它可以使用外圍類模板的模板引數;template
struct a_class_template
template
t1 get();
};
// 類模板的成員函式模板在類模板外的實現方法
template
template
t1 a_class_template::get()
2.當外圍類模板被例項化時,內部巢狀類模板不會被例項化,只有確實需要它的完整類型別時,它才會被例項化;
3.巢狀在類模板內部的類隱含地成為類模板。
如下示例:
簡單總結,有以下幾條:template
class classa
void dispa()
void dispc()
;class classb //巢狀在類模板的類隱含的成為模板
void dispb()
;private:
t0 m_data;
};int main()
1.如果乙個非模板類包含乙個模板友元,則所有友元例項被授權可以訪問該類
如下:
2.如果乙個類模板包含乙個非模板友元,則友元被授權可以訪問所有類模板例項。class normalclass
;template t>
class a
如下:
* 3.如果乙個類模板與友元模板擁有相同的型別引數,則類與友元為一對一的友好關係*template
class a
;
如下:
4.如果乙個類模板與友元模板擁有不同的型別引數,則類的每乙個例項授權給所有模板例項。//前置宣告
template
class classa;
template
class classb;
template
class classb
;//如下
classb ca; //classa是本物件的友元
classb ia; //classa是本物件的友元
如下:
通函式模板特化一樣,當對於某種型別的引數,模板無法寫成通用或右更好的實現時,就要對該種型別進行特化。template
class classa ;
類模板的特化分為全特化與偏特化:全特化就是全部限定實現的具體型別,偏特化就是如果這個模板有多個型別,那麼只限定其中的一部分
如下:
templateclass classa
; template<>
class classa
; template class classa
; //下面3句分別呼叫類模板、全特化和偏特化
classa t1(2.0f, 3.0f);
classa t2(1,'a');
classa t3('a',2);
c 模板簡介
一.函式模板 1.模板的基本格式 include using namespace std template void swap t a,t b,t size 執行結果 a交換之前1234 b交換之前2345 a交換之後2345 b交換之後1234 2.模板實參的使用 include using na...
C 模板簡介(零) 簡介
首先推薦 c 官方模板介紹 sfinae 很多內容被 concepts 取代 meta programming 很多內容被 constexpr 函式取代 tuple any 看完上面介紹你就覺得全部講的毫無用處了 建議你先了解一下模式匹配與模板偏特化是什麼東西,否則你可能 4 篇文章都看不懂。模式匹...
C 模板類簡介
c 模板類簡介 模板就是實現 重用機制的一種工具,它可以實現型別引數化,即把型別定義為引數,從而實現了真正的 可重用性。模版可以分為兩類,乙個是函式模版,另外乙個是類模版。1.模板的概念。我們已經學過過載 overloading 對過載函式而言,c 的檢查機制能通過函式引數的不同及所屬類的不同。正確...