參考:ibm編譯器中國開發團隊部落格
其中幾個比較好的例子,下面的class 都可以換成 typename,向後相容性比較好。
而且typename是較class更加新的標準,具體class 可能導致的問題可見這篇文章,講的特別詳細
知無涯值c++ typename
struct t1{}; struct t2{}; struct t3{};
void func(t1 arg)
void func(t2 arg)
void func(t3 arg)
int main(void)
輸出:
called t1
called t2
called t3
這個很簡單,編譯器根據傳遞給函式的實參型別來決定呼叫哪個函式,這就是過載解析。在呼叫前,編譯器有乙個候選函式呼叫列表:
void func(t1);
void func(t2);
void func(t3);
每個呼叫函式都有各自的引數,編譯器根據引數最匹配原則選擇相應的函式
模板函式:
#include #include struct t1{}; struct t2{}; struct t3{};
using namespace std;
template void func(a a1, b a2, c a3)
int main(void)
輸出:
a: t1
b: t2
c: t3
在這個使用了乙個函式模板的例子中,編譯器有乙個帶有3個未知型別的候選呼叫函式,它將實參 (x1,x2,x3)傳遞給函式func中的3個形參(a,b,c),可以很容易看到編譯器是如何推導出模板引數的:
a t1
b t2
c t3
編譯器例項化了模板函式;將實參傳遞給模板函式中的形參以建立乙個真正的函式:
void func(t1 a1, t2 a2, t3 a3)
如果有其他的候選過載函式,他們都將會和非模板函式的例子一樣被繫結在一起,然後在過載解析中根據實參型別呼叫相應的函式。
過載解析允許使用者建立同乙個函式的不同版本,這些函式將根據傳進來的引數的型別,做一些不同的操作。編譯器會根據型別資訊來選擇相應的函式。通過使用模板函式,使用者可以定義帶引數化型別的函式,從而減少需要定義的過載函式的個數。編譯器會選擇正確的模板並為使用者建立候選的過載函式。
類模板:
#include #include using namespace std;
struct t1{}; struct t2{}; struct t3{};
template struct container
};int main(void)
輸出:
primary a: t1 i: 10
在這個例子中,編譯器並不會玩什麼把戲,這個例子中只有乙個類container, 它接收了實參並傳遞給模板引數,推導出a即為t1,i為10。
含有乙個全特化的類模板:
#include #include using namespace std;
struct t1{}; struct t2{}; struct t3{};
template struct container
};template <> struct container
};int main(void)
輸出:
primary a: t1 i: 10
complete specialization t3, 99
在這個例子中有兩個模板,其中乙個是全特化模板,即模板中模板引數全部指定為確定的型別。特化(specialized)不過是乙個花哨的術語,意思是形參不再為形參,它們已經有了確定的值。我更傾向於使用「全特化」這個術語,感覺這更容易讓人理解。但是在大多數的c++書籍,包括標準c++,都將其稱為「顯示特化」。
現在編譯器有了兩個類名都為container的類模板,類模板被過載:
template struct container;
template <> struct container;
當編譯器執行到containertest1, 對於引數:
偏特化+全特化的乙個例子:
#include #include using namespace std;
struct t1{}; struct t2{}; struct t3{};
template struct container
};template struct container
};template <> struct container
};int main(void)
輸出:
primary a: t1 i: 10
complete specialization t3, 99
partial specializationt2 and 25
partial specializationt3 and 25
此例有3個候選模板:
template struct container;
template struct container;
template <> struct container;
模板1是帶有兩個模板引數的主模板,模板2是帶有乙個模板引數的偏特化模板,模板3是無模板引數的全特化模板。
如前面所說,偏特化也僅是乙個花哨的術語,偏特化模板中的模板引數沒有被全部確定,需要編譯器在編譯時進行確定。
當編譯器編譯執行到containertest4,引數為:
最後乙個例子:
#include #include using namespace std;
struct t1{}; struct t2{}; struct t3{};
template struct container
};template struct container
};template <> struct container
};int main(void)
輸出:
primary a: t1 i: 10
complete specialization t3, 99
partial specialization t3 and 75
partial specialization t3 and 25
本質上,偏特化模板的匹配和選擇過程與過載解析非常類似。實際上,在非常複雜的偏特化情況下,編譯器可能就是將偏特化直接譯成函式,然後直接呼叫過載解析來處理。
過載解析和偏特化匹配都用到了模板引數推導。
c 學習 模板特化和偏特化
模板特化和偏特化 合肥市炮兵學院計算中心 230031 摘要 本文通過例子介紹了在 c 標準庫中廣泛使用的模板特化和偏特化,並指出了模板特化和偏特化的定義規則和應用規則。1.引言 c 中的模板分為類模板和函式模板,雖然它引進到c 標準中的時間不是很長,但是卻得到了廣泛的應用,這一點在stl中有著充分...
c 學習 模板特化和偏特化
模板特化和偏特化 合肥市炮兵學院計算中心 230031 摘要 本文通過例子介紹了在 c 標準庫中廣泛使用的模板特化和偏特化,並指出了模板特化和偏特化的定義規則和應用規則。1.引言 c 中的模板分為類模板和函式模板,雖然它引進到c 標準中的時間不是很長,但是卻得到了廣泛的應用,這一點在stl中有著充分...
強化學習1 什麼是強化學習
強化學習 reinforcement learning,rl 一般也稱作增強學習,和心理學 動物行為的研究等領域有比較久的淵源。心理學中,強化 指生物受到外界環境中的某些刺激後,自覺或者不自覺調整應對策略,達到趨利避害。舉個例子。馬戲團訓練動物時 比方說猴子 訓導員首先會發出某種指令 比方說抬一下手...