【C++泛型学习笔记】模板基础知识补充

学习参考书籍:王健伟《C++新经典:模板与泛型编程》

奇异的递归模板模式

派生类作为基类的模板参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
template<typename T>
class A // 基类模板
{

};

class B : public A<B> // 派生普通类
{

};

template<typename T>
class C : public A<C<T>> // 派生类模板
{

};

应用:

  • 在基类中使用派生类对象。
  • 通过友元函数将派生类的一些重复代码在基类中实现,减少派生类代码量。
  • 基类中调用派生类接口。

混入

将传入的模板参数作为该类模板的父类

1
2
3
4
5
template<typename... T>
class A : public T...
{
A() : T()... {} // 继承父类的构造函数
}

模板代码组织结构

只有当模板被源程序调用时,编译器才会根据调用传入的模板参数实例化对应模板,进而生成相关代码。编译器在生成代码时,需要能够找到模板的代码实现部分,故**(类)模板的定义和实现通常都放在.h头文件中**,不能分成不同文件进行编写。对于特化版本,应该紧跟在泛化版本之后编写。

模板显示实例化

试想一下,每当使用模板时,编译器就会对其实例化一次,那么如果多个不同源文件中对对同一个模板进行相同模板参数的实例化,那么整个编译过程和结果就会变得非常冗余,没必要做重复性的工作。所以我们可以通过在一个源文件中对模板进行实例化定义,在其他源文件中对实例化进行声明(声明这个具体类型的模板已经在其他文件中实例化过了,所以本文件中不再进行实例化),以此(显示实例化)来解决上述问题。示例如下:

1
2
template A<int>;	// 类模板的实例化定义
template void func(int a, float b); // 函数模板的实例化定义
1
2
extern template A<int>;		// 类模板的实例化声明
extern template void func(int a, float b); // 函数模板的实例化声明