所谓templates arguments是当编译器实例化一个template时用来替换template parameter的值。编译器以数种不同的机制来决定以何值替换template parameters:
explicit template arguments(显式指定模板自变量):可在template名称之后跟着一个或多个明确的template arguments,并以角括号括起来。这个完整的名称称为template-id。
injected class name (内植式类别名称):在带有参数P1,P2....的class template X作用域中,
template X的名称与template-id X<P1, P2, ...>等价。
default template arguments: 如果存在可用的default template arguments.我们可在class template具体实现中省略不写 explicit template arguments.然而,即使每一个参数都有默认值,你也必须把开闭两个角括号写上(即使括号内什么也没有)。
argument deduction(自变量推导):编译器可根据function call arguments推导出function template argument。其他某些情况下,编译器也可能动用推导机制。如果所有template argument都可以推导得出,你就无需在function template名称后面加写角括号。
1. 函数式模板自变量Function Template Argument
2.类别引数Type Argument
3.非类型引数Nontype Argument
4.双重模板自变量Template Template Argument
5.等价Equivalence
当两组template arguments的元素一一对等时,我们称这两组自变量等价。对于type arguments, typedef的名称并不影响对比过程最终被比较的是typedef所指代的type。对于整型的nontype arguments,比较的是自变量值,与自变量表达式无关。下面例子解释刚才这个概念:
template <typename T, int I >
class Mix;
typedef int Int;
Mix<int , 3*3> * p1;
Mix<Int, 4+5>* p2; //p2和p1是同一类型,两者等价
一个由function template产生的函数,和一个常规函数,无论如何不会被编译器看作等价,即使它们的类型和名称完全相同。这对class members造成两个重要结果:
1)由member function template产生的函数不会覆盖虚函数virtual。
2)由construct template产生的构造函数不会被当作default copy构造函数(同样道理,由assignment template产生的assignment运算符不会被当作一个copy-assignment运算符)