编译期 Type List 是一种模板元编程结构,本质为递归模板别名或类模板,不产生运行时对象,所有操作均在编译期完成,与 std::tuple 等运行时容器有根本区别。

什么是编译期 Type List?它不是 std::vector<type>
编译期 Type List 是一个模板元编程结构,本质是递归模板别名或类模板,不产生运行时对象,所有“遍历”“查找”“拼接”都在编译期完成。它和 std::tuple 不同:后者是运行时可实例化的类型容器,而 Type List 通常连 sizeof 都为 0,纯粹用于类型推导与 SFINAE 分支选择。
用 variadic template + recursion 实现最简版本
核心思路是用模板参数包承载类型,用继承或嵌套别名展开。下面是最小可行实现:
template <typename... Ts>
struct type_list {};
// 空列表终止条件
template <>
struct type_list<> {};
// 获取第一个类型(head)
template <typename T, typename... Ts>
struct type_list<T, Ts...> {
using head = T;
using tail = type_list<Ts...>;
};
注意:head 和 tail 只在非空时定义,直接访问空 type_list<> 的 head 会编译失败。常见错误是忘记特化或误用 using 而非 typedef(C++11+ 推荐 using)。
- 不要试图在
type_list<>中定义head—— 这违反单一职责,且破坏 SFINAE 友好性 - 若需安全取 head,应配合
std::void_t或decltype+ SFINAE 写 traits,而不是硬加默认类型 - 这种实现不支持随机索引(如
at<2>),需要额外模板偏特化,性能取决于深度(O(N) 编译时间)
如何判断某个类型是否在 list 中(type_in_list_v)
这是典型递归 trait 场景,依赖 partial specialization 和 constexpr static 成员变量:
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
立即学习“C++免费学习笔记(深入)”;
template <typename T, typename List>
struct type_in_list : std::false_type {};
template <typename T, typename... Ts>
struct type_in_list<T, type_list<T, Ts...>> : std::true_type {};
template <typename T, typename U, typename... Ts>
struct type_in_list<T, type_list<U, Ts...>>
: type_in_list<T, type_list<Ts...>> {};
使用时写 type_in_list_v<int, my_list> 即可。关键点:
- 必须按顺序写偏特化:先匹配首项相等,再匹配首项不等 + 递归 tail,否则编译器无法区分
- 如果 list 很长,编译器可能因模板实例化深度超限报错(如 GCC 默认 900 层),可通过
-ftemplate-depth=调整 - 不支持重复类型去重;若需唯一性检查,得额外写
unique_listtrait
为什么不用 std::tuple 或 std::variant 替代?
std::tuple 是运行时实体,有构造、内存布局、sizeof,而 type_list 是纯类型占位符,零开销。例如想做“仅对 list 中存在的类型启用函数重载”,就必须用 type_list + enable_if_t<type_in_list_v<T, allowed_types>>,而非 tuple —— 后者无法参与 SFINAE 判定。
容易被忽略的是:type_list 的“长度”只能通过偏特化计算(如写 size<type_list<int, char>>::value),不能像 sizeof...(Ts) 那样直接展开 —— 因为 Ts... 在类模板内部已固化为参数包,外部不可见。所以实际工程中常配合 template<typename...> using pack_size = std::integral_constant<size_t, sizeof...(Ts)> 这类辅助别名。

















