C 泛型程式設計與函式模板

2021-07-28 07:35:25 字數 3639 閱讀 2848

一、函式模板

1、定義:

代表了乙個函式家族,該函式與型別無關,在使用時被引數化,根據實參型別產生函式的特定型別版本。

2、格式

template

//但是建議使用

typename

,避免和

class

類混淆

template 《型別1變數1, 型別2 變數2, ….. > 返回型別 函式名(形參表)

3、作用域

typedef

intt;

template

t>

t add(t

left,t

right)

//t的作用域在模板形參之後到模板宣告或定義的末尾之間使用,遵循名字遮蔽規則。

t global ;此處的t是全域性的typedef的 int t;

4、編譯:

模板被一共被編譯了兩次:

第一階段:例項化之前,檢查模板**本身,看看模板是否出現語法錯誤,如:忘記分號或者變數名拼錯,並檢查引數型別是否匹配,在此階段,編譯器只能檢查部分的錯誤。

5、例項化:

template

t add(t left, t right)

cout << add('1', '2')<

cout << add(1, '1') <

cout << add(1, '1') << endl;//

編譯不通過

二.模板形參:(型別形參和非型別形參)

型別形參:

1、型別形參轉換:(編譯器只會執行兩種轉換)

(1)const轉換:接受const引用或者const指標的函式可以分別用非const物件的引用或者指標來呼叫。

template

void funtest(constt&p)//

本來應該是

const int *p

而實際是

int*const p,

(2)陣列或函式到指標的轉換:如果模板形參不是引用型別,則對陣列或函式型別的實參應用常規指標轉換。陣列實參將當做指向第乙個元素的指標,函式實參當做指向函式型別的指標.

void funtest1()

template

void funtest(t p)

int arr[10];

funtest(arr);//

執行結果:

int*

funtest(funtest1);//

執行結果:

void <__cdecl*>

注意:

1、模板形參的名字在同一模板形參列表中只能出現一次。

2、模板形參用<>括起來,且模板形參不能為空,多個形參之間必須加「,」。

3、模板形參可以是型別形參和非型別形參,型別形參必須使用關鍵字class或typename。

4、使用模板型別形參和內建型別或者自定義型別使用方法完全一樣,可用作指定函式形參型別,返回型別,區域性變數和強轉型別轉換。

非模板型別引數:

1、概念:

非型別模板引數,顧名思義,模板引數不限定於型別,普通值也可作為模板引數。它是模板內部定義的常量,在需要常量表示式的時候,可以使用非模板型別。而使用基於常量的模板時,你必須顯式地指定這些值,模板方可被例項化。

2、用途:

乙個非型別引數可以是乙個整型,或者是乙個指向物件或函式型別的指標或引用。

繫結到非型別整型引數的實參必須是乙個常量表示式。繫結到指標或引用非型別引數的實參必須具有靜態的生存期。

3、例如:

template

void funtest(t(&array)[n])

}template

int compare(const

char(&p1)[n],const

char(&p2)[m])

int_array[5];

funtest(_array);/*

000434fc  call        funtest(041528h)  */

char_array1[5];

funtest(_array1);/*

00234518  call       funtest(023152dh) */

compare("hi", "hello");

/*編譯器會按照字面常量的大小來代替n和

m,從而例項化模板,

注意:編譯器會在乙個字串字面常量的末尾插入乙個空字元作為終結符,

因此編譯器會例項化處以下版本:

intcompare(const char(&p1)[3], const char(&p2)[6]) ps

:非型別模板引數的模板必須是常量表示式。 */

三、模板函式過載

類似於通函式一樣,模板函式也可以過載。(注意:模板函式既不是函式也不是類)

int _max(intleft,int right)

template

t _max(const t&left, const t & right)

template

t _max(t left, t mid,t right)

int main()

四、模板函式特化

1、原因:

當函式模板需要對某些型別進行特別處理,稱為函式模板的特化。因為,在某些情況下,通用模板定義對於某個型別可能是錯誤的,或者編譯通過不了,即使編譯通過了,也不是我們想要得到的答案,這時候,需要我們對函式模板進行特化。

2、特化格式:

template

<>

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

3、例如:

template

//普通函式模板

int is_equal(t t1, t t2)

template

<>//

特化函式模板

int is_equalchar*>(const

char*constp1,const

char*constp2)

const

char*p1 = "bbbb";

const

char*p2 = "aaaa";

cout<< is_equal( p1, p2) << endl;//p1>p2

應該返回

1,而實際結果卻是-1;

//p1 0x0108dc70 "bbbb" char *

//p2 0x0108dc78 "aaaa" char * //

比較時,直接比較的是兩個位址的大小,而沒有比較兩個指標的內容

4、特化位置:

特化必須出現在模板例項的呼叫之前,否則在編譯的時候,找不到特化函式模板,則會按照普通模板函式進行呼叫。

函式模板(泛型程式設計)

函式模板就是將函式型別引數化,方便程式設計。1 普通函式模板 include using namespace std template template是告訴編譯器,要開始泛型程式設計了,並用t替代函式的引數型別 void myswap t a,t b template 定義兩個泛型,其實定義乙個也...

泛型程式設計 函式模板

當函式的業務邏輯相同但是函式的引數不相同時,讓型別引數化,讓程式設計師能夠方便程式設計,就用到了泛型程式設計。基本語法 includeusing namespace std 函式的業務邏輯一樣但是函式的引數不一樣 void myswap01 int a,int b void myswap02 cha...

C 泛型程式設計 函式模板 類模板

以前我們寫過乙個簡單的交換函式。我們不難發現交換函式是與型別有很大關係的,int,double.那麼如何實現乙個通用的交換函式呢?void swap int left,int right void swap double left,double right void swap char left,c...