模板的模板參數

模板的模板參數 （ template template parameter ） 是指C + + 語言程序設計中 ， 一個模板的參數是模板類型 。 只有類模板允許其模板參數是模板類型 ； 函數模板不允許具有這樣的模板參數 （ 此處有爭議 ） 。 模板的模板參數可以有默認值 。 例如 ： template <class T = float> struct B { }; template < template <class TT = float> class T > struct A { inline void f; inline void g; }; template < template <class TT> class T > void A <T>:: f { T < > t; / / error - TT has no default template argument } template < template <class TT = char> class T > void A <T>:: g { T < > t; / / OK - T <char> } 模板的模板參數 ， 其實參應當是類模板名字或者 [ [ 模板 _ ( C++ ) #. E 5.88. AB.E5 .90.8 D.E6.A8.A1.E6 .9 D.BF | 別名模板 ] ] （ alias template ） 。 當模板的模板參數做 “ 形參實參結合 ” 時 ， 僅考慮把實參的基本 （ 即未特化 ） 類模板與模板的模板形參做匹配 ； 不考慮實參的偏特化類模板 ， 即使偏特化後的參數列表與模板的模板形參匹配得上 。 例如 ： template < typename T, template < typename ELEM, typename ALLOC = std:: allocator <ELEM> > class CONT = std:: deque > / / deque的基本型有2個模板參數 class Stack { private: CONT <T> elems; / / OK ！ / / … }; 當模板的模板參數被實例化時 ， 考慮採用該模板參數的偏特化版本 。 如果在實例化之處該偏特化版本仍不可見 ， 且如果它是可見的則應該當採用 ， 這時該程序爲病態 。 例如: template <class T> class A { / / primary template int x; }; template <class T> class A < T * > { / / partial specialization long x; }; template < template <class U> class V > class C { V <int> y; V < int * > z; }; C <A> c; / / V <int> within C <A> uses the primary template, so c.y.x has type int / / V < int * > within C <A> uses the partial specialization, so c.z.x has type long 當一個模板的模板形參 （ 稱作P ） 與一個作爲實參的模板 （ 稱作A ） 匹配時 ， 要求P與A各自的模板形參列表的對應成員滿足 ： 具有相同種類 （ 類型參數 、 非類型參數 、 模板作爲參數 ） ； 如果二者是非類型的模板參數 ， 則其具體類型應相等; 如果二者是模板作爲參數 ， 則遞歸執行上述模板的模板參數形實匹配規則 ； 如果P是一個 [ [ 可變參數模板 ] ] ， 即P的模板形參列表包含了模板參數包 （ template parameter pack ） ， 則這個模板參數包應該匹配A中0個或者多個模板參數或者匹配A中的對應的模板參數包 。 例如 ： template <class T> class A { / * ... * / }; template < class T, class U = T > class B { / * ... * / }; template < class ... Types > class C { / * ... * / }; template < template <class> class P > class X { / * ... * / }; template < template < class ... > class Q > class Y { / * ... * / }; X <A> xa; / / OK X <nowiki> <B> </nowiki> xb; / / ill - formed: default arguments for the parameters of a template argument are ignored X <C> xc; / / ill - formed: a template parameter pack does not match a template parameter Y <A> ya; / / OK Y <nowiki> <B> </nowiki> yb; / / OK Y <C> yc; / / OK template <class T> struct eval; template < template < class, class ... > class TT, class T1, class ... Rest > struct eval < TT < T1, Rest ... >> { }; template <class T1> struct A; template < class T1, class T2 > struct B; template <int N> struct C; template < class T1, int N > struct D; template < class T1, class T2, int N = 17 > struct E; eval < A <int> > eA; / / OK: matches partial specialization of eval