template是模板定义的必需语法标记,仅出现在函数模板、类模板及特化声明前;typename与class在模板参数处等价但推荐用typename;template后必须带尖括号且不可为空,且不能出现在局部作用域。

template 是模板定义的起始标记,不是“关键字用法”而是语法必需的声明头,不写它,编译器根本不认这是模板。
template 出现在哪几种地方
它只出现在三种上下文中,且位置固定:
- 函数模板定义前:
template<typename t></typename>void foo(T x) { ... } - 类模板定义前:
template<typename t></typename>class vector { ... } - 模板特化或偏特化声明前:
templatevoid print(int); 或 template<typename t></typename>class container{ ... }
它不会出现在调用处、实现体内部(比如成员函数定义里),也不会在普通函数或类里突然冒出来。一旦看到 template<...></...> 开头的行,就说明接下来是一个模板实体的声明或定义。
typename 和 class 在 template 里真能随便换吗
能,但仅限于模板参数声明位置 —— 即 template<typename t></typename> 和 template<class t></class> 完全等价,编译器不做区分。
立即学习“C++免费学习笔记(深入)”;
但注意两个实际约束:
- 不能混用:同一模板声明中别写成
template<typename t class u></typename>,虽然多数编译器放行,但可读性差,也违背惯例 - typename 更准确:当模板参数本身是嵌套类型(如
T::value_type)时,必须用typename告诉编译器“这是个类型”,这时class就不能替代了
所以推荐统一用 typename,避免后续在依赖名称场景下被迫切换。
为什么 template 后面必须带 ?里面可以空吗
必须带,且不能空 —— template 是合法的(表示无模板参数,用于全特化或变量模板),但 template 单独出现是语法错误。
常见误写:
- ❌
template void func();—— 缺少,编译失败 - ❌
template class A;放在类定义外却没给完整声明 —— 这只是前向声明,若后续定义不匹配会链接失败 - ✅
template<typename t></typename>是最常见形式;template<auto n></auto>(C++17 起)或template<int n></int>也合法,属于非类型模板参数
template 看似“空”,其实表示零个模板参数,和函数的 void f() 类似,语义明确,不是省略。
容易被忽略的限制:template 不能出现在局部作用域
你不能在函数内部、if 分支里、甚至 namespace 别名后写 template —— 它只能在全局、命名空间或类作用域中出现。
典型错误场景:
- ❌ 在
main()里写template<typename t> T add(T a, T b) { return a + b; }</typename>—— 编译器报错 “template declaration not allowed here” - ❌ 在某个
if constexpr分支内尝试动态定义模板 —— C++ 不支持运行时生成模板,所有模板必须在编译期可见
这意味着:模板不是“运行时工具”,它是编译器在翻译阶段展开代码的蓝图,位置决定了它能否被实例化和查找。放在错的地方,连定义都算不上。


















