模板的模板参数(template template parameter)是指C++语言程序设计中,一个模板的参数是模板类型。只有类模板允许其模板参数是模板类型;函数模板不允许具有这样的模板参数(此处有争议)。
模板的模板参数可以有默认值。例如:
template struct B {};
template class T> struct A {
inline void f();
inline void g();
};
template class T> void A::f() {
T<> t; // error - TT has no default template argument
}
template class T> void A::g() {
T<> t; // OK - T
}
模板的模板参数,其实参应当是类模板名字或者别名模板(alias template)。当模板的模板参数做“形参实参结合”时,仅考虑把实参的基本(即未特化)类模板与模板的模板形参做匹配;不考虑实参的偏特化类模板,即使偏特化后的参数列表与模板的模板形参匹配得上。 例如:
template >
class CONT = std::deque> //deque的基本型有2个模板参数
class Stack {
private:
CONT elems; // OK!
//…
};
当模板的模板参数被实例化时,考虑采用该模板参数的偏特化版本。如果在实例化之处该偏特化版本仍不可见,且如果它是可见的则应该当采用,这时该程序为病态。 例如:
template class A { // primary template
int x;
};
template class A { // partial specialization
long x;
};
template class V> class C {
V y;
V z;
};
C c; // V within C uses the primary template, so c.y.x has type int
// V within C 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 A { / ... / };
template class B { / ... / };
template class C { / ... / };
template class P> class X { / ... / };
template class Q> class Y { / ... / };
X xa; // OK
X xb; // ill-formed: default arguments for the parameters of a template argument are ignored
X xc; // ill-formed: a template parameter pack does not match a template parameter
Y ya; // OK
Y yb; // OK
Y yc; // OK
template struct eval;
template class TT, class T1, class... Rest>
struct eval> { };
template struct A;
template struct B;
template struct C;
template struct D;
template struct E;
eval> eA; // OK: matches partial specialization of eval
参考文献
评论 (0)