C 模板簡介

2021-07-10 02:39:31 字數 4158 閱讀 1848

標籤: c++ template

對於c++模板,之前很少使用,這裡整理下,以備後忘。

先來看下面2個加法函式:

int

sum(int a, int b)

double

sum(double a, double b)

上面的2個函式,雖然它們的返回值和引數型別不一致,但函式名和函式體完全一致。如果能提煉出乙個通用函式,並適用不同的資料型別,則會大大提高**的可重用性。c++的模板就可以解決這種問題。

模板是c++支援引數化多型的工具,它可以實現型別引數化,即使類中的資料成員或成員函式的引數、返回值取得任意型別。模板是一種對型別進行引數化的工具,能減少程式設計師編寫型別無關的**。

c++的模板可分為函式模板和類模板,通過函式模板具體化的函式稱為模板函式,通過類模板具體化的類稱為模板類。

所謂函式模板實際上是建立乙個通用函式,其涵涵素型別額形參型別不具體指定,用乙個虛擬的型別來代表,這個通用函式就稱為函式模板

定義乙個函式模板的格式並不複雜,形式如下:

template ...>

返回值 函式名(函式引數列表)

其中,template是宣告模板的關鍵字;typename用來標識的形參名用來表示乙個虛擬型別,當使用函式模板時,會將其具體化為具體的型別,typename關鍵字也可以用class替換。

下面,對剛開始的2個函式,使用函式模板定義並呼叫

#include 

template

t sum(t a, t b)

int main()

它是如何兼用int和double型別的呢:

上面編寫的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()

普通類中的成員函式模板可以在類中當場實現,也可以在類外單獨實現。在類外實現時,由於類不是模板,無需在類名後增加模板實參列表。

類模板的成員函式還可以有額外的模板引數,如:

template

struct a_class_template

template

t1 get();

};

// 類模板的成員函式模板在類模板外的實現方法

template

template

t1 a_class_template::get()

1.在類模板中允許再嵌入模板,因此類模板的巢狀類也是乙個模板,它可以使用外圍類模板的模板引數;

2.當外圍類模板被例項化時,內部巢狀類模板不會被例項化,只有確實需要它的完整類型別時,它才會被例項化;

3.巢狀在類模板內部的類隱含地成為類模板。

如下示例:

template

class classa

void dispa()

void dispc()

;class classb //巢狀在類模板的類隱含的成為模板

void dispb()

;private:

t0 m_data;

};int main()

簡單總結,有以下幾條:

1.如果乙個非模板類包含乙個模板友元,則所有友元例項被授權可以訪問該類

如下:

class normalclass 

;template t>

class a

2.如果乙個類模板包含乙個非模板友元,則友元被授權可以訪問所有類模板例項。

如下:

template

class a

;

* 3.如果乙個類模板與友元模板擁有相同的型別引數,則類與友元為一對一的友好關係*

如下:

//前置宣告

template

class classa;

template

class classb;

template

class classb

;//如下

classb ca; //classa是本物件的友元

classb ia; //classa是本物件的友元

4.如果乙個類模板與友元模板擁有不同的型別引數,則類的每乙個例項授權給所有模板例項。

如下:

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 的檢查機制能通過函式引數的不同及所屬類的不同。正確...