泛型程式設計(generic programming)是一種程式設計正規化fmlqt,通過將型別引數化來實現在同乙份**上操作多種資料型別,泛型是一般化並可重複使用的意思。泛型程式設計最初誕生於c++中,目的是為了實現c++的stl(標準模板庫)。
模板(template)是泛型程式設計的基礎,乙個模板就是乙個建立類或函式的藍圖或公式。例如,當使用乙個vector這樣的泛型型別或者find這樣的泛型函式時,我們提供足夠的資訊,將藍圖轉換為特定的類或函式。
一、函式模板
乙個通用的函式模板(function template)就是乙個公式,可用來生成針對特定型別或特定值的函式版本。模板定義以關鍵字template開始,後面跟乙個模板引數列表,列表中的多個模板引數(template parameter)以逗號分隔。模板引數表示在類或函式定義中用到的型別或值。
1、型別引數
乙個模板型別引數(type parameter)表示的是一種型別。我們可以將型別引數看作型別說明符,就像內建型別或類型別說明符一樣使用。型別引數前必須使用fmlqt關鍵字class 或typename:
template // typename和class一樣的
t function(t* p)
關鍵字typename和class是一樣的作用,但顯然typename比class更為直觀,它更清楚地指出隨後的名字是乙個型別名。
編譯器用模板型別實參為我們例項化(instantiate)特定版本的函式,乙個版本稱做模板的乙個例項(instantiation)。當我們呼叫乙個函式模板時,編譯器通常用函式實參來為我們推斷模板實參。當然如果函式沒有模板型別的引數,則我們需要特別指出來:
int a = 10;
cout << function(&a) << endl; // 編譯器根據函式實參推斷模板實參
cout << function(&a) << endl; // 指出模板引數為int
2、非型別引數
在模板中還可以定義非型別引數(nontype parameter),乙個非型別引數表示乙個值而非乙個型別。我們通過乙個特定的型別名而非關鍵字class或typename來指定非型別引數:
// 整形模板
template
void add()
// 指標
template
void func1(const char* str)
// 引用
template
void func2(const char* str)
// 函式指標
template
void func3(const char* c)
void print(const char* c)
char arr[9] = "template"; // 全域性變數,具有靜態生存期
int main()
當例項化時,非型別引數被乙個使用者提供的或編譯器推斷出的值所替代。乙個非型別引數可以是乙個整型,或者是乙個指向物件或函式的指標或引用:繫結到整形(非型別引數)的實參必須是乙個常量表示式,繫結到指標或引用(非型別引數)的實參必須具有靜態的生存期(比如全域性變數),不能把普通區域性變數 或動態物件繫結到指標或引用的非型別形參。
二、類模板
相應的,類模板(class template)是用來生成類的藍圖。與函式模板的不同之處是,編譯器不能為類模板推斷模板引數型別,所以我們必須顯式的提供模板實參。與函式模板一樣,類模板引數可以是型別引數,也可以是非型別引數,這裡就不再贅述了。
template
class array ;
// 類模板外部定義成員函式
template
array::array(t arr, int s)
; array intarr(b, 5);
intarr.print();
return 0;
}類模板的成員函式
與其他類一樣,我們既可以在類模板內部,也可以在類模板外部定義其成員函式。定義在類模板之外的成員函式必須以關鍵字template開始,後接類模板引數列表。
template
return_type class_name::member_name(parm-list)
預設情況下,對於乙個例項化了的類模板,其成員函式只有在使用時才被例項化。如果乙個成員函式沒有被使用,則它不會被例項化。
類模板和友元
當乙個類包含乙個友元宣告時,類與友元各自是否是模板是相互無關的。如果乙個類模板包含乙個非模板的友元,則友元被授權可以訪問所有模板的例項。如果友元自身是模板,類可以授權給所有友元模板的例項,也可以只授權給www.cppcns.com特定例項。
// 前置宣告,在將模板的乙個特定例項宣告為友元時要用到
template class pal;
// 普通類
class c ;
// 模板類
template class c2 ;
類模板的static成員
類模板可以宣告static成員。類模板的每乙個例項都有其自己獨有的static成員物件,對於給定的型別x,所有class_name型別的物件共享相同的乙份static成員例項。
template
class foo ;
template
void foo::print()
template
int foo::i = 10; // 初始化為10
int main()
我們可以通過類型別物件來訪問乙個類模板的static物件,也可以使用作用域運算子(::)直接訪問靜態成員。類似模板類的其他成員函式,乙個static成員函式也只有在使用時才會例項化。
本文標題: c++函式模板與類模板例項解析
本文位址:
C 函式模板與類模板例項解析
c 函式模板與類模板例項解析 本文針對c 函式模板與類模板進行了較為詳盡的例項解析,有助於幫助讀者加深對c 函式模板與類模板的理解。具體內容如下 泛型程式設計 generic programming 是一種程式設計正規化,通過將型別引數化來實現在同乙份 上操作多種資料型別,泛型是一般化並可重複使用的...
函式模板例項
函式模板例項 這是值得考慮一下如何模板函式的實現在c 因為未來的教訓將關閉一些這些概念。原來,c 不編譯模板函式直接。相反,在編譯的時候,當編譯器呼叫乙個函式模板,它複製的模板功能,並與實際型別代替模板型別引數!與實際型別的函式被呼叫函式模板例項。讓我們來看看這樣乙個例子看看。首先,我們有乙個模板函...
C 模板實戰1 函式模板
模板本身不是可編譯的 而是用來指導編譯器生成可編譯 的文字。1 函式模板引數 函式模板引數可以根據模板實參自動推導,也就是說可以從實參自動推導的模板引數可以省略書寫,但是要注意以下幾個規則 1 編譯器只根據函式呼叫時給出的實參列表推導模板引數值,與函式引數無關的模板引數無法推導 2 與函式返回值相關...