Template parameters有三种类型:
- 类型参数Type parameters
- 非类型参数 Non-type Parameters
- 双重模板参数 Template Template Parameters
所谓模板参数template parameters是在模板声明语句的参数化子句(parameterized clause)中声明的变量。Template parameters不一定要署名:
template
class X;
但是当template程序中需要用到某个template parameter时,后者就必须署名。另外,后面声明的template parameters可以用到先声明的template parameters的名称,反之不然:
template T* Root, template class Struture; 1. 类型参数Type Parameters Type parameters可以采用关键词typename 或关键词class导入,两者等价。其声明形式是:关键词typename 或class后面跟一个简单标识符,该符号后面可跟一个逗号以便区隔下一个参数,也可以使用闭锁角括号结束参数子句,或跟一个等号=标识出预设模板自变量default template argument。 在template 声明语句中type parameter的作用非常类似typedef的名称。例如不能使用如class T这样的完整名称,即使T确实表示一个class type: template class List { class Allocator* allocator;//Error friend class Allocator; //Error ... }; 2. 非类型参数NonType Parameters Nontype template parameter是指那些可在编译期或链接期确定其值的常数。此种参数的类型必须是以下三者之一: 令人惊讶的是,nontype parameter的声明在某种情况下也以关键词typename为前缀词 template typename T::Allocator* Allocator> //nontype parameter class List; Nontype parameters 也可以是functions类型或array类型,但它们都会退化为对应的pointer类型: template template Nontype template parameters的声明类似变量声明,但不能加上static、mutable之类的修饰。你可以加上const或volatile,但如果修饰词出现在参数类型的最外层,编译器会忽略它们: template template 最后一点,nontype parameters总是右值rvalues:它们不能被取值,也不能被赋值, 3. 双重模板参数Template Template Parameter template template parameters是一种class template占位符,其声明方式和class template类似,只是不能使用关键词struct和union: template class C> //OK void f(C template struct C> //Error void f(C template union C> //Error void f(C 在它们的作用域内,你可以像使用class template那样地使用template template parameters。 1)template template parameters的参数也可以default template arguments 如果客户端没有为响应的参数指定自变量,编译器就会使用这些预设自变量: template
typename A = MyAllocator> class Container> class Adaptation { Container ... }; 2)template template parameters中,template parameter的名称只能被用于template template parameter 的其他参数声明中。 template class Buf> class Lexer { static char storage[5]; Buf ... }; template class List> class Node { static T* storage; ... }; 3)通常template template parameter中的template parameters名称并不会在其他地方用到,因此,未被用到的template parameter可以不署名。 例如,上面的Adaption template可被声明为: template typename = MyAllocator> class Container> class Adaptation { Container ... } 4. 预设的模板引数Default Template Arguments 目前,只有class template的声明语句可以存在default template argument。无论何种template parameter都可以有预设的自变量,当然它必须匹配对应参数。很明显,预设自变量不能相依于其自身参数,但可以相依于之前声明的参数: template class List; 和函数的预设自变量一样,某个参数(不论是调用参数还是模板参数)带有预设自变量的条件是:其后续所有参数也都有预设自变量。 后续参数的预设自变量通常写在同一个template声明语句中,但也可以写在该template更早的某个声明语句中。例如, template typename T4= char , typename T5 = char> class Quintuple; //OK template typename T4, typename T5> class Quintuple; //OK: T4, T5先前已经有默认值 template typename T4, typename T5> class Quintuple; //错误:T1不能有默认值,因为T2没有默认值 此外,我们也不能重复指定default template arguments: template class Value; template class Value;



