模板以一或多个参数化,形参有三种:类型模板形参、非类型模板形参和模板模板形参。
当提供了模板实参,或仅对于函数和 (C++17 起)模板,当模板实参被推导出时,它们替换各模板形参,以获得模板的一个特化(specialization),即一个特定类型或一个特定函数左值。特化亦可显式提供:对类和函数模板都允许全特化,只允许对类模板。
在要求完整对象类型的语境中引用某个类模板特化时,或在要求函数定义存在的语境中引用某个函数模板特化时,除非模板已经被显式特化或显式实例化,否则模板即被实例化(instantiate)(它的代码被实际编译)。类模板的实例化不会实例化其任何成员函数,除非它们也被使用。在连接时,不同翻译单元生成的相同实例被合并。
声明 | - | 类(包括 struct 和 union),,函数或,命名空间作用域的静态数据成员,变量或类作用域的静态数据成员, (C++14 起)或 (C++11 起)的声明。它亦可定义模板特化。 |
形参列表 | - | 非空的的逗号分隔列表,其中每项是非类型形参、、模板形参或任何这些的之一。 |
概念名制约表达式 | - | 见制约与概念 (C++20 起) |
模板形参列表可以后随一个可选的 ,它指定各模板实参上的制约。 | (C++20 起) |
模板名 < 形参列表 > | ||
指名模板特化的 简单模板标识 指名一个类。
指名别名模版特化的 模板标识 指名一个类型。
指名函数模板特化的 模板标识 指名一个函数。
- 实参数量不多于形参,或有形参是模板形参包,
- 每个无默认模板实参的不可推导的非包形参都有一个实参,
- 每个模板实参都与对应的模板形参相匹配,
- 替换每个模板实参到其后续模板形参(若存在)中均成功,而且
无效的 简单模板标识 是编译时错误,除非它指名的是函数模板特化(该情况下可适用 )。
如果在 简单模板标识 的模板名指名受制约的非函数模板或受制约的模板模板形参,但不是作为未知特化的成员的成员模板,而且 简单模板标识 中的所有模板实参均非待决,则必须满足受制约模板的各项关联制约: | (C++20 起) |
模板化实体
模板化实体(某些资料称之为 "temploid")是任何定义(或对于 lambda-表达式 为创建)于模板定义内的实体。下列所有实体都是模板化实体:
- 类/函数/变量 (C++14 起)模板
- 概念 (C++20 起)
- 模板化实体的成员(例如类模板的非模板成员函数)
- 作为模板化实体的枚举的枚举项
- 任何模板化实体中定义或创建的实体:局部类,局部变量,友元函数,等等
例如,以下模板中: