模板的模板参数

1、概念

         模板的模板参数(template template parameters),这个名字有点长,首先要理解什么是模板的模板参数。需要知道的是函数模板是不支持模板的模板参数的,所以这儿所指的模板的模板参数就是类模板的模板参数,即对一个类模板,它的模板参数本身也是一个模板,更确切地说是一个类模板。

2、例子

         为了说明怎样使用模板的模板参数,以STL中的容器适配器stack为例较为恰当。下面是SGI-STL stack的部分源码:

template >
class stack
{
protected:
         Sequence c;
//…
};

         从源码可以看出来,stack的默认容器是deque,一般可以满足用户的需求,用户也可以另外指定容器。如指定vector作为stack的底层容器, 定义如下:

         stack > s;        //别忘了”#include”和 “#include

stack类模板的第二个模板参数是一个类型,在这儿我们指定为vector,从stack的定义我们可以知道,程序员如果要替换缺省的内部容器的话,必须两次指定元素的类型,如上面两次指定了int。然而,如果我们使用模板的模板参数,就可以只指定容器的类型而不需要指定所含元素的类型,于是我们可以这样创建一个stack对象,如下:

stack s;

为了获得这个特性,我们需要把stack类模板的第二个模板参数指定为模板的模板参数(呵呵,我们在修改SGI-STL源码),如下:

template class Sequence = std::deque >
class stack
{
protected:
         Sequence c;
//…
};

我们把第2个模板参数声明为了一个类模板:

         template class Sequence  = std::deque

缺省值也从std::deque变成了std::deuqe,第二个参数必须是一个类模板,并由第一个模板参数传递进来的类型进行实例化。于是我们可以如下创建一个stack对象:

         stack s;

如果我们在编译器上编译,会得到错误信息:缺省值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 Sequence = std::deque>

class stack;

它的第二个模板参数template class Sequence = std::deque也是一个类模板,它只有一个模板参数 ,即template中的E,但对std::deque却有两个模板参数(见上面的声明),故错误信息会提示缺省值std::deque和模板的模板参数Sequence不匹配。于是我们可以如下重新声明stack类,如下:

template >
			class Sequence = std::deque>
class stack
{
         protected:
         Sequence c;
         //…
}

         由于我们在stack类的实现中并没有用到模板参数E和Alloc, 所以我们可以将其省略。如下:

template >
class Sequence = std::deque> class stack;

3、注意事项:

(1)由于STL版本比较多,故实现也存在差异,如空间配置器就有所不同,所以上面代码不具有可移植性。

(2)模板的模板实参要求与模板的模板参数精确匹配。

(3)函数模板不具有模板的模板参数

4、更多参考资料

[1]侯捷著.STL源码剖析[M],湖北华中科技大学出版社.2011.12

[2][美]David Vandevoorde,Nicolai M.Josuttis著.陈伟柱译.C++ Templates.北京.人民邮电出版社

[3][美]Nicolai M.Josuttis著.侯捷,孟岩译.C++标准程序库.湖北.华中科技大学出版社

你可能感兴趣的:(C/C++,STL)