- 模板的介紹
模板是懶人的福音,是提高開發效率和降低維護成本的利器。
簡單來說,模板就是一種萬能的型別,我們使用這種型別編寫出來的函式就是模板函式;使用這種型別作為類成員編寫的類就是模板類。在使用模板的時候需要我們傳入實際的型別對模板進行填充(這個步驟由編譯器來完成),這樣對於相同的邏輯我們就不必再去過載太多的函式了,若是**有問題也只用改乙份**的邏輯,因此提高了**的復用率的同時也減少了維護**的耗費。
- 函式模板
- 類模板
- 模板特例化
- 模板的應用——型別萃取
型別萃取是用來萃取型別的某些特性,從而能讓函式根據型別特性的不同實現不同的功能。
有乙個常用的場景就是拷貝函式,這個函式需要根據傳入引數的型別進行拷貝。對於自定義型別的拷貝,比如說string,如果僅僅只是進行了記憶體拷貝,就會拷貝乙份指標過去,進而導致二次釋放的問題。於是我們首先要對引數型別進行判斷,而型別萃取是最為高效快捷的一種方法。
為了書寫方便先定義兩個結構體型別
//是內建型別
struct truetype };
//不是內建型別
struct falsetype
};
然後寫乙個模板類用以判斷傳入的引數型別
template
<
class
t>
struct typetraits
;
最後根據需要書寫特例化模板,這裡我簡單寫一些內建型別
template
<
>
struct typetraits<
char
>
;template
<
>
struct typetraits<
int>
;template
<
>
struct typetraits<
short
>
;template
<
>
struct typetraits<
bool
>
;template
<
>
struct typetraits<
double
>
;template
<
>
struct typetraits<
float
>
;template
<
>
struct typetraits<
long
>
;template
<
>
struct typetraits<
unsigned
int>
;
寫乙個函式來測試一下:
template
<
class
t>
void
ispodtype
(t& x)
else
};
這樣,對ispodtype函式傳入內建型別,就會列印ispodtype,否則就會列印notpodtype。
- 模板分離編譯
分離編譯:每個原始檔單獨編譯生成目標檔案,鏈結時再將所有目標檔案整合成可執行檔案。
由於模板是編譯期進行例項化的,因此若是模板宣告的標頭檔案和模板實現的原始檔分離,而使用模板的原始檔只包含了模板宣告的標頭檔案,那麼在編譯期編譯器不會對模板進行例項化,因為此時編譯期在標頭檔案中找不到模板函式的例項化,於是會發生鏈結錯誤。
- typename 和 class的區別
參考:c++中typename和class在宣告模板時的區別
前面說過,如果typename或class宣告模板引數,效果是一樣的,那為什麼c++要引進typename呢?
假設有如下場景,我們的模板引數需要傳乙個類型別
classa;
classb:
public a
;template
<
class
t>
void
test()
試著編譯一下發現編譯器報錯了,因為在編譯器眼裡t::a是乙個錯誤的語法,它不知道這個t是個啥,它通過作用域運算子訪問到的a是個啥,所以編譯器懵了。而在前面宣告了typename關鍵字之後,編譯器就會將t預設為乙個類,這種巢狀依賴的問題也就解決了。 C 入門學習 模板
我們已經學過過載 overloading 對過載函式而言,c 通過函式引數 引數個數 引數型別 的正確匹配來呼叫過載函式。比如。為求兩個數的最大值,我們定義 max 函式須要對不同的資料型別分別定義不同過載 overload 版本號。函式1 int max int x,int y 函式2 float...
C 函式模板入門
先看如下2個函式 交換int型別兩個數字 void myswapint int a,int b 交換double資料 void myswapdouble double a,double b 通過對比,兩個函式僅僅是函式名不同,傳參型別不同,但 的邏輯完全一樣。為了減少重複 的編寫。我們可以通過如下方...
c 模板(template)入門介紹
普通函式與函式模板的呼叫規則 模板具體化 類模板 示例 include includeusing namespace std 這裡使用函式模板 t templatevoid swapvalue t a,t b 多個模板引數宣告方式 void func t1 t1,t2 t2 int main inc...