C++模板的使用一共有如下几种状况。c++
而本篇介绍模板模板参数。web
模板参数就是模板的参数,咱们通常指定为T
类型,实际上可使用任何的名字,例如指定一个Foo
的模板参数:svg
temlate<typename Foo>
Foo calc(const Foo& a, const Foo& b)
{
return a+b;
}
而模板模板参数则是模板的参数又是一个模板,例如:函数
template<typename T, template<typename U> typename Container>
class XCls
{
private:
Container<T> c;
};
模板的第一个参数是T
类型,第二个参数是一个Container
,他是一个能够指定一个U
类型的变量。ui
那么如何使用他呢?spa
template<typename T>
class test
{
private:
T t;
};
int main(void)
{
XCls<std::string, test> mylst1;
return 0;
}
咱们能够定义一个模板类,而后将其如上方式传入就能够了。c++11
可是若是传入一个容器呢?好比:list
code
XCls<string, list> mylst1;
若是编译就会报错。咱们分析一波:xml
将string 和 list
传入到类XCls
中,而后就会定义一个list<string>
的c
变量,这样看起来是能够的,所以咱们使用list
容器的时候就是list<一个类型>
,可是这里为何就不行呢?是由于list
容器实质上是有第二参数的,虽然第二参数有默认的参数,正如咱们日常使用的那样,只须要指定一个参数,可是在这里没法经过编译,所以,咱们使用以下解决办法:string
template<typename T>
using Lst = std::list<T, std::allocator<T>>;
XCls<std::string, Lst> mylst2;
// 编译时须要加上std=c++11
使用C++11
的using
关键字的新功能,来定义一个类型的别名,并且使用在模板的状况下,所以咱们编译时要指定std=c++11
而后咱们将list
的别名Lst
传入进入,就能够编译经过。
若是是这么定义的模板参数,还会是模板模板参数吗?
template<typename T, typename Sequence = list<T>>
class stack
{
private:
Sequence c;
};
咱们定义了一个stack
的模板类,模板参数第一个是T
类型,第二个是一个Sequence
类型,有一个默认的类型是list<T>
。
使用方法有两种:
stack<int> s1;
stack<int, deque<int>> s2;
第一种,只指定了第一个模板参数,使用第二个默认的模板参数。
第二种,指定了两个模板参数。
可是!这不是模板模板参数。由于,一旦指定了第一个模板参数,那么第二个参数的类型就会肯定,而真正的模板模板参数,第二个模板参数和第一个模板参数的类型是没有关系的,能够指定为第一个模板参数的类型,也能够指定为其余类型。所以,这不是模板模板参数!!!
以上都是本人本身的理解,若有错误,请谅解并恳请您的指正。