C 模板詳解

2021-10-25 09:40:09 字數 3339 閱讀 6367

模板分類

類模板假如現在需要實現乙個交換整數的函式,很簡單就能實現,但是如果沒有說交換型別,那麼可能需要寫各種型別的過載,函式過載雖然可以實現,但是這麼做很麻煩,函式的復用性很低,且**的可維護性比較低,乙個出錯可能讓所有過載都錯。

void swap(int& left, int& right) 

void swap(double& left, double& right)

void swap(char& left, char& right)

//、、、、、、、、、、出現乙個新型別就要新增乙個

那麼怎麼解決這個問題呢?這個時候我們就可以引入模板的概念

了解模板之前先了解一下泛型程式設計的概念,泛型程式設計就是指編寫與型別無關的通用**,是**復用的一種手段,而模板呢就是泛型程式設計的基礎

那麼什麼是模板呢?

模板就像我們現實中的模具,沒有使用這個模具的時候是不會生產出任何東西的,只有在你倒入原料才會生產出東西,你倒入塑料材料就會產出乙個塑料模型,倒入金屬液就會產出乙個金屬模型。

再回到引言上的問題,我們使用模板就是為了能夠編寫與型別無關的**。如果不用模板,那麼解決引言上的問題要寫不同型別的函式來完成函式過載,但如果使用模板的話就只用寫乙個swap模板函式就可以實現不同型別的swap函式了。

模板通常有兩種形式:函式模板和類模板

什麼是函式模板呢?函式模板實際上是代表了乙個函式家族,建立了乙個通用函式,這個函式裡面的所用到的所用型別,包括形參型別、返回值型別、區域性變數型別都可以不具體指定,在使用的時候才會被引數化,根據實參型別產生函式的特定版本。

函式模板針對僅引數型別不同的函式

template

<

typename t1,

typename t2,..

..typename tn>

/class t1..

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

typename和class都是用來定義模板引數的關鍵字,兩者沒有區別。

以引言的交換函式為例,使用函式模板寫乙個swap的模板函式:

template

>

//template也可以

void

swap

(t& left,t& right)

當我們呼叫這個swap模板函式時,型別t就會被呼叫時的型別代替,舉個例子,swap(a,b),兩個引數都是int型的,那麼這時t就會被替代為int型,模板函式就被替換為swap(int& a,int& b)。

需要注意的是模板的宣告或定義只能在全域性,命名空間或類範圍內進行。即不能在區域性範圍,函式內進行,比如不能在main函式中宣告或定義乙個模板。

其實模板函式並不是真正的函式,在編譯階段,編譯器呼叫函式模板時,編譯器會根據實參的型別來推演出模板的型別,然後產生特定具體型別的函式。

1.隱式例項化:讓編譯器根據實參推演模板引數的實際型別

template

<

class

t>

t add

(const t& left,

const t& right)

intmain()

但是假如要編譯下面這段**就會報錯,因為在編譯階段的時候,編譯器推演實參型別時,通過a1把t推演為int型別,但是通過b1又把t推演為double型別,但是模板引數列表只有乙個t,此時編譯器就無法確定該使用哪個型別替換t,從而報錯。(編譯器一般不會進行型別轉換的操作)

template

<

class

t>

t add

(const t& left,

const t& right)

intmain()

那麼怎麼解決這個問題呢?有兩種處理方式

第一種方法使用者自己強制轉換型別

int

main()

第二種方法就是使用顯式例項化

2.顯式例項化:在<>中指定引數的實際型別

還是以上面**舉例

int

main()

先看這段**

// 加法模板函式 

template

<

class

t>

t add

(t left, t right)

// 專門處理int的加法函式

intadd

(int left,

int right)

void

test()

我們知道add模板函式在遇到int型別的實參時是會例項化出乙份int型別的add函式**的,那麼上面這段**裡的int型別add函式和add函式模板是否可以同時存在呢?

可以同時存在,而且該函式模板還可以被例項化為這個非模板函式。

在test()裡,add(1,2)呼叫add函式時,因為已經有了int型別的add函式,此時肯定是直接呼叫處理int型別的add函式更快,因為模板函式還要推演完實參型別後再生成乙份特定處理int型別的**。但是如果我強制要使用模板函式,那麼使用add(1,2)就可以呼叫函式模板例項化後add版本。

c++ 除了支援函式模板,還支援類模板(class template)。函式模板中定義的型別引數可以用在函式宣告和函式定義中,類模板中定義的型別引數可以用在類宣告和類實現中。類模板的目的同樣是將資料的型別引數化。

類模板針對僅資料成員和成員函式型別不同的類。

template

<

class

t1,calss t2,..

..,calss tn>

class 類模板名稱

;

一旦宣告了類模板就可以用形參名(t1,t2…tn)來宣告類中的成員變數和成員函式,舉例:

template

>

class

a;

類模板例項化和函式模板例項化不同,類模板例項化需要在類模板名稱後跟《例項化型別》,需要注意的是,類模板中不存在推演的,例如a<2> s,此時就會報錯,編譯器沒法把2推演為int型,在<>裡面一定要明確指定型別。

用上面的**舉例,我們例項化乙個a< int > m,那麼類a中所有使用模板形參的地方都會被int替代:

class

a;

c 模板詳解

c 模板分為2類 1.函式模板 格式 template void swap t a,t b 呼叫時 int a,b swap a,b double d1,d2 swap d1,d2 但是下面寫法是錯誤的 swap int,int 不能在函式呼叫的引數中指定模板形參的型別,對函式模板的呼叫應使用實參推...

C 模板詳解

模板是c 支援引數化多型的工具,使用模板可以使使用者為類或者函式宣告一種一般模式,使得類中的某些資料成員或者成員函式的引數 返回值取得任意型別。模板是一種對型別進行引數化的工具 通常有兩種形式 函式模板和類模板 函式模板針對僅引數型別不同的函式 類模板針對僅資料成員和成員函式型別不同的類。使用模板的...

c 模板詳解

模板是c 支援引數化多型的工具,使用模板可以使使用者為類或者函式宣告一種一般模式,使得類中的某些資料成員或者成員函式的引數 返回值取得任意型別。模板是一種對型別進行引數化的工具 通常有兩種形式 函式模板和類模板 使用模板的目的就是能夠讓程式設計師編寫與型別無關的 比如編寫了乙個交換兩個整型int 型...