template template parameter是让模板接收另一模板作为参数的机制,语法为template,要求严格匹配参数类型与数量,不支持非类型参数模板如std::array,常用于容器适配器和元编程。

什么是 template template parameter?
它就是让一个模板能接收「另一个模板」作为参数,而不是某个具体类型或值。比如你想写一个容器适配器,要支持 std::vector、std::list、std::deque 这些不同模板,但又不想为每个都写一遍特化——这时候就得用 template template parameter。
语法怎么写?容易漏掉什么?
基本形式是 template class Tmpl>,注意三点:
-
class Tmpl不能写成typename Tmpl(C++ 标准强制要求用class) - 内层模板参数必须用
typename...或明确列出(如typename T, typename Alloc),不能只写 - 如果目标模板有非类型参数(比如
std::array的5),它无法被这种形式匹配——std::array不符合template签名class
template class Container>
struct container_wrapper {
template
using type = Container;
};
为什么 std::vector 有时传不进去?
因为 std::vector 实际定义是 template,带默认参数。而 template template parameter 要求参数个数「严格匹配」声明的形参列表——你写了 template,它就只认变参;若写成 template,则无法接受带默认 Alloc 的调用。
常见解法是统一用变参形式,并在内部转发:
立即学习“C++免费学习笔记(深入)”;
一个简单的网上书店系统,有图书管理、会员注册、评论发表、购物车等基本应用,后台有:定单管理、评论管理、用户管理、图书管理等功能模块。为北大青鸟学员练习之用,可以做为入门者的学习参考之用。采用了VS2005的master模板DB_51aspx下为Sql数据库文件,附加即可,注意:除修改web.config中的Sql连接信息以外还要对App_Code/Class1.cs中的Sql登录信息也要做对应的修
template class Container>
struct wrapper {
template
using rebind = Container; // 安全:依赖 Container 自己的默认参数
};
这样传 std::vector、std::list 都行;但传 std::array 会失败,因为它第二个参数是 size_t,不是类型。
实际用在哪?有没有更现代的替代?
典型场景包括:容器元函数(如提取 value_type)、策略类组合、类型擦除包装器。C++17 后部分需求可用 constexpr if + 变参模板推导绕过,但 template template parameter 仍是唯一能「静态约束模板身份」的方式。
容易忽略的一点:它不参与 SFINAE 推导失败的静默处理——如果传入的模板签名不匹配,错误发生在实例化阶段,报错位置可能很深,且提示常含糊(比如 “expected a template-name before ‘static_assert 检查 is_template_v 类型特征(需自定义)来提前拦截。









