第 10 章 基本模板的术语

“类模板”还是“模板类”

其实差不多,但为了描述准确,都统一用类模板来描述,类似地,使用函数模板、成员模板、成员函数模板和变量模板,但不使用模板函数、模板成员、 模板成员函数和模板变量。

替换、实例化和特化

处理使用模板的源代码时,C++ 编译器必须用具体的模板实参替换模板中的模板形参。有时, 这种替换是暂时的: 编译器可能需要检查替换是否有效。
通过替换模板的具体参数,为模板中的常规类、类型别名、函数、成员函数或变量实际创建定 义的过程,称为模板实例化。
但目前还没有标准或公认的术语,来表示通过模板参数替换来创建非定义声明的过程。我们已 经看到了一些团队使用的部分实例化或声明的实例化,但这不通用。也许更直观的术语是不完全实 例化 (类模板的情况下,会生成不完整的类)。
由实例化或不完全实例化 (即类、函数、成员函数或变量) 产生的实体一般称为特化。
C++ 中实例化过程并不是产生特化的唯一方法。替代机制允许开发者显式地指定与模板参数的 特殊替换绑定的声明

声明和定义

声明是一种 C++ 构造,在 C++ 作用域中引入或重新引入一个名称。此介绍会包含该名称的部 分类别,但进行有效声明时不需要详细信息。

class C; // a declaration of C as a class
void f(int p); // a declaration of f() as a function and p as a named parameter
extern int v; // a declaration of v as a variable

当声明的结构已知时,或对于变量,必须分配存储空间时,声明就变成了定义。对于类类型定 义,必须提供带括号的主体。对于函数定义,这就必须提供 (一般情况下) 用大括号括起来的函数体, 或者必须将函数指定为 =default 或 =delete。对于变量,初始化或缺少 extern 说明符会导致声明变成 定义。

定义规则

C++编程中的单一定义规则(One Definition Rule, ODR),这是一个确保同一程序的不同翻译单元(Translation Unit)中,同一个实体(如函数、类、变量等)只能有一个定义的规则。

  1. 在整个程序中,非内联函数(包括函数模板)和非内联成员函数(含函数模板的全特化)只能定义一次。违反这一规则会导致链接错误,因为链接器在合并多个翻译单元时会发现同一个符号有多次定义。
  2. 全局变量(除非使用extern关键字声明且未初始化)和静态数据成员(无论是在类内定义还是类外定义,或者声明为inline或constexpr)在一个程序中也只能有一个定义。如果在多个翻译单元中定义了相同的全局变量或静态数据成员,也会违反ODR。
  3. 类类型 (包括结构和联合)、模板 (包括偏特化,但不包括全特化) 以及内联函数和变量在每个 翻译单元中最多定义一次,而且所有这些定义应该相同。

模板实参与模板形参

区分模板形参和模板实参很重要。简而言之,“参数由实参初始化”。学术界中,参数有时称为实际参数,而声明参数称为形式参数。

或者更准确地说:
• 模板参数是那些列在模板声明或定义中的关键字 Template 之后的参数 (示例中是 T 和 N)。
• 模板实参是替代模板形参的项 (示例中是 double 和 10)。与模板形参不同,模板实参可以不仅
仅是“名称”。

总结

• 对于属于模板的类、函数和变量,请分别使用类模板、函数模板和变量模板。
• 模板实例化是通过将模板形参替换为具体实参,来创建常规类或函数的过程。产生的实体是特化模板类型。
• 类型可以是完整的或不完整的。
• 根据单一定义规则 (ODR): 程序中,非内联函数、成员函数、全局变量和静态数据成员应该只
定义一次。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值