Skip to content

模板与模板元编程(Template & Metaprogramming)专题 ​

HPC/Infra 面试偏重「模板能力」:类型萃取、编译期计算、SFINAE、CRTP、concepts、推导规则。这是区分「会用模板」和「懂元编程」的分水岭,常作为硬核区。

问题清单(含答案) ​

1. 函数模板 / 类模板 / 模板特化 / 偏特化 区别?

答案

函数模板/类模板是"蓝图",用具体类型实例化出真代码;特化给特定参数写专用实现,全特化固定全部参数、偏特化仍留模板参数(函数模板不能偏特化)。详见 basics.md。

2. 模板的「编译期实例化」是什么?为什么模板放头文件?

答案

编译器针对每种用到的类型"生成"一份具体代码(实例化)。定义必须放头文件,因为编译器要看到完整定义才能实例化、无跨编译单元链接。

3. 类型萃取 type_traits?remove_reference/is_same 原理?

答案

编译期"查询/变换类型"的元函数。remove_reference<T> 用偏特化匹配 T&/T&& 剥掉引用;is_same 用 is_same<T,T> 特化判相等。详见 type-traits.md。

4. SFINAE 原理与 enable_if?

答案

SFINAE = 替换失败非错误,候选匹配失败不报错而是从重载集移除。enable_if<条件, T> 据此做条件模板重载。详见 sfinae.md。

5. constexpr 元编程?

答案

用 constexpr 函数/变量在编译期计算;C++14 起可写循环、C++17 可 if constexpr 剪枝,替代 C++03 的模板递归。详见 constexpr-meta.md。

6. CRTP 与静态多态(对比虚函数)?

答案

class X : Base<X>,基类用 static_cast 安全向下转型实现静态多态,无虚函数运行时开销;虚函数是运行期多态。详见 crtp.md。

7. 折叠表达式 fold (C++17)?

答案

(pack op ...) 把参数包折叠成表达式(如求和 (args + ...)),替代递归展开。

8. concepts(C++20) 如何替代 SFINAE?

答案

用 concept/requires 直接表达类型约束,重载更简洁、报错信息更清晰(不再 SFINAE 那一长串),也用于约束 auto。

9. 模板推导规则倒错题?

答案

值传递剥引用和顶层 const、数组/函数退化成指针;引用折叠 &&+&→&、&&+&&→&&;auto 推导与模板推导完全一致。详见 deduction.md。

10. std::is_same_v + if constexpr 剪枝?

答案

if constexpr (is_same_v<T,int>) 是编译期分支,只实例化命中的分支,未用分支不编译(避免不同类型走同一份代码出错)。

子文档 ​

文件内容
index.md本总览
basics.md模板基础、实例化、特化/偏特化、非类型参数
type-traits.mdtype_traits 原理、remove_、is_、conditional、tuple 实现模型
sfinae.mdSFINAE、enable_if、void_t 探测惯用法
constexpr-meta.mdconstexpr 函数 C++14、编译期递归、if constexpr 剪枝
crtp.mdCRTP / 静态多态 / 混入(mixin)
concepts.mdC++20 requires/concept 语法与 use-case
deduction.md模板参数推导深规则(引用折叠、auto 对应)+ 经典题

学习顺序建议 ​

先 basics → sfinae/type-traits(工具)→ constexpr-meta(计算)→ crtp(模式)→ concepts(新写法)。每篇末尾有自测/推导题,盖住答案先自己做。

提示:HPC/AI infra 里真正的「元编程」大量用于编译期维度展开、生成访问代码、policy-based 设计、kernel 分派,而不是面试背 SFINAE 诅咒——理解「为什么需要」(编译期选型/性能/诊断)比炫技更重要。

糌粑的面经笔记 · VitePress 版