1、概念
模板的模板参数(template template parameters),这个名字有点长,首先要理解什么是模板的模板参数。需要知道的是函数模板是不支持模板的模板参数的,所以这儿所指的模板的模板参数就是类模板的模板参数,即对一个类模板,它的模板参数本身也是一个模板,更确切地说是一个类模板。
2、例子
为了说明怎样使用模板的模板参数,以STL中的容器适配器stack为例较为恰当。下面是SGI-STL stack的部分源码:
template >
class stack
{
protected:
Sequence c;
//…
};
从源码可以看出来,stack的默认容器是deque,一般可以满足用户的需求,用户也可以另外指定容器。如指定vector作为stack的底层容器, 定义如下:
stack
stack类模板的第二个模板参数是一个类型,在这儿我们指定为vector
stack
为了获得这个特性,我们需要把stack类模板的第二个模板参数指定为模板的模板参数(呵呵,我们在修改SGI-STL源码),如下:
template class Sequence = std::deque >
class stack
{
protected:
Sequence c;
//…
};
我们把第2个模板参数声明为了一个类模板:
template
缺省值也从std::deque
stack
如果我们在编译器上编译,会得到错误信息:缺省值std::deque和模板的模板参数Sequence不匹配。其实如是你熟悉STL,应该知道问题出在哪儿。对于STL的容器vector,deque, list, map, set, multimap, multiset,它们都有一个缺省的模板参数,它便是空间配置器allocator,它负责容器对空间的配置与管理。配置器实现了动态空间配置,空间管理,空间释放,它本质上是一个类模板(class template)。SGI-STL的空间配置器实现相对比较复杂,内容比较多,也不是本篇的主题,有兴趣的网友可以参考侯捷的STL源码剖析。下面给出SGI-STL allocator和deque的类模板声明,如下:
template
class allocator;
template >
class deque;
从上面的声明可以看出deuqe和allocator只是一个类模板,而allocator是类模板deque的第二个模板参数,是缺省的空间配置器(用户也可以定义自己的空间配置器)。现在我们再来分析错误原因。
对于stack类模板声明:
template template class stack; 它的第二个模板参数template 由于我们在stack类的实现中并没有用到模板参数E和Alloc, 所以我们可以将其省略。如下: 3、注意事项: (1)由于STL版本比较多,故实现也存在差异,如空间配置器就有所不同,所以上面代码不具有可移植性。 (2)模板的模板实参要求与模板的模板参数精确匹配。 (3)函数模板不具有模板的模板参数 4、更多参考资料 [1]侯捷著.STL源码剖析[M],湖北华中科技大学出版社.2011.12 [2][美]David Vandevoorde,Nicolai M.Josuttis著.陈伟柱译.C++ Templates.北京.人民邮电出版社 [3][美]Nicolai M.Josuttis著.侯捷,孟岩译.C++标准程序库.湖北.华中科技大学出版社template
template