定义:指一个模板,它本身的参数类型就是模板,在英语原文中是“template template parameter”。
例如:template<typename T1, template<typename T2> class CONT>,就是将template参数类型声明中的一个(原本应该是typename T2)替换成template<typename T2> class CONT。
关键点:
1. 在模板的模板参数中,class(指上面例子中标红色的class) 不能被替换成typename。在模板中,如果不能区分的哪应该使用typename和class,可以全部都用class替代,typename和class的作用基本相同,而typename出现得比较晚。同时它也支持缺省值。
- 例:template<typename T1, template<typename T2> class CONT> class A{.........} // 正确
- template<typename T1, template<typename T2> typename CONT> class A{.........} // 错误
- template<typename T1, template<class T2> class CONT> class A{.........} // 正确
- template<typename T1, template<typename T2> typename CONT=std::list> class A{.........} //正确
2.以上面的例子为例,在使用第二个参数,必须是一个模板类。
3.函数模板不支持模板的模板参数。
- 例:template<template<typename T> class CONT> void func{.........} //错误
4.在模板中,可以前面的模板参数声明可以被后面的使用。
- 例:template<typename T1,
- template<typename T2, typename ALLOC=std::allocator<T2> > class CONT=std::list>
- class A{.........} //假设T1和T2的类型一样,那T2可以用T1替代(当然类型不一样也可以,只要容器空间分配不 出问题)。同时,如果T2没用的话可以省略不写。
5.函数定义
- 例:template<typename T1, template<typename T2> typename CONT=std::list>
- class A{ void func(); .........}
- template<typename T1, template<typename T2> typename CONT=std::list>
- void A<T1,/*list*/>::func(){.....} //如果使用编译器(Qt)自动生成定义的话,会报错,因为没有此行中红色标注的
6.要了解重载解析的相关内容,尤其是二义性和演绎部分。