C++ 模板机制与 String 类深度解析
一、模板基础
1. 函数模板
什么是模板?简单来说,它就是一个模具。往里面倒入不同的材料(类型),就能得到不同材质的铸件。
比如实现一个交换函数,这很容易:
void Swap(int& a, int& b) {
int temp = a;
a = b;
b = temp;
}
但这只能交换整型。如果想交换浮点数或字符呢?难道要写一堆重载函数吗?虽然可以通过函数重载解决,但代码重复严重,维护成本高,显然不是最佳方案。
这就是函数模板的用武之地,它是泛型编程的基础。泛型编程旨在编写与类型无关的通用代码,极大提升复用率。
定义格式如下:
template <typename T> // 或者 template <class T>
void Swap(T& a, T& b) {
T temp = a;
a = b;
b = temp;
}
这里的 template<typename T> 定义了一个模板家族。typename 和 class 在此处通常可以互换,区别在于后续更复杂的特化场景,初学者可先视为等同。
2. 原理与实例化
函数模板本身不是函数,而是编译器生成具体函数的蓝图。在编译阶段,编译器会根据传入的实参类型推演并生成对应的函数版本,这个过程称为实例化。
隐式实例化
让编译器根据实参自动推导类型:
int a = 10, b = 20;
Swap(a, b); // 编译器推导出 T 为 int
显示实例化
在函数名后显式指定类型:
double x = 1.1, y = 2.2;
Swap<double>(x, y); // 强制指定 T 为 double
3. 匹配原则
当存在非模板函数和同名函数模板时,调用规则如下:
- 优先非模板:如果非模板函数和模板都能匹配,且其他条件相同,优先调用非模板函数。
- 更好匹配选模板:如果模板能产生出比非模板函数更精确匹配的实例,则选择模板。
- :模板函数不允许像普通函数那样进行隐式的类型转换(如 转 ),必须严格匹配或显式指定。


