模板機制為c++提供了泛型程式設計的方式,在減少**冗餘的同時仍然可以提供型別安全。 特化必須在同一命名空間下進行,可以特化類模板也可以特化函式模板,但類模板可以偏特化和全特化,而函式模板只能全特化。 模板例項化時會優先匹配」模板引數」最相符的那個特化版本。
c++的模板機制被證明是圖靈完備的,即可以通過模板元程式設計(template meta programming)的方式在編譯期做任何計算。類模板和函式模板的宣告方式是一樣的,在類定義/模板定義之前宣告模板引數列表。例如:
// 類模板
template class a;
// 函式模板
template t max(const t lhs, const t rhs)
通過全特化乙個模板,可以對乙個特定引數集合自定義當前模板,類模板和函式模板都可以全特化。 全特化的模板引數列表應當是空的,並且應當給出」模板實參」列表:
// 全特化類模板
template <>
class a;
// 函式模板
template <>
int max(const int lhs, const int rhs)
注意類模板的全特化時在類名後給出了」模板實參」,但函式模板的函式名後沒有給出」模板實參」。 這是因為編譯器根據int max(const int, const int)
的函式簽名可以推導出來它是t max(const t, const t)
的特化。
上述函式模板不需指定」模板實參」是因為編譯器可以通過函式簽名來推導,但有時這一過程是有歧義的:
template void f()
template <>
void f()
此時編譯器不知道f()
是從f()
特化來的,編譯時會有錯誤:
error: no function template matches function template specialization 'f'
這時我們便需要顯式指定」模板實參」:
template void f()
template <>
void f()
類似於全特化,偏特化也是為了給自定義乙個引數集合的模板,但偏特化後的模板需要進一步的例項化才能形成確定的簽名。 值得注意的是函式模板不允許偏特化,這一點在effective c++: item 25中有更詳細的討論。 偏特化也是以template
來宣告的,需要給出剩餘的」模板形參」和必要的」模板實參」。例如:
template class a;
函式模板是不允許偏特化的,下面的宣告會編譯錯:
template void f(){}
template void f(){}
但函式允許過載,宣告另乙個函式模板即可替代偏特化的需要:
template void f(){} // 注意:這裡沒有"模板實參"
多數情況下函式模板過載就可以完成函式偏特化的需要,乙個例外便是std
命名空間。std
是乙個特殊的命名空間,使用者可以特化其中的模板,但不允許新增模板(其實任何內容都是禁止新增的)。 因此在std
中新增過載函式是不允許的,在effective c++: item 25中給出了乙個更詳細的案例。 C 模板 全特化與偏特化
模板 模板定義 模板就是實現 重用機制的一種工具,它可以實現型別引數化,即把型別定義為引數,從而實現了真正的 可重用性。模版可以分為兩類,乙個是函式模版,另外乙個是類模版。大白話 c 是一門強型別語言,編寫一段通用的邏輯,可以把任意型別的變數傳進去處理,通過把通用邏輯設計為模板,擺脫了型別的限制,極...
C 模板全特化 偏特化
大家都對c 的模板程式設計應該都能很熟練使用了,下面就是一段很簡單不過的例子了 模板函式 templatevoid func t num1,n num2 cout num1 num1 num2 num2 static bool comp t num1,n num2 return num1 特化其實就...
C 模板的偏特化與全特化
類模板和函式模板的宣告方式是一樣的,在類定義 模板定義之前宣告模板引數列表。例如 類模板template class a 函式模板 template t max const t lhs,const t rhs 結構體模板 template struct stacknode 通過全特化乙個模板,可以對...