概述
模板是 C++ 中实现参数化多态的编译期机制,通过类型参数抽象数据结构与算法,使同一份源码可被实例化为多个特化版本,从而达成零运行时开销的泛型复用。
为什么需要模板?
场景还原:重复代码问题
例如编写 Swap 函数:
void Swap(int& left, int& right) {
int temp = left;
left = right;
right = temp;
}
每新增一个类型,就需要复制一份代码。这不仅耗时间,还容易引入逻辑错误(如漏写赋值语句)。必须使用泛型来破障。
函数模板
语法结构
template<typename T>
void Swap(T& left, T& right) {
T temp = left;
left = right;
right = temp;
}
注意:typename 和 class 在此处等价。
隐式实例化
int totalCount = 42;
int anotherCount = 100;
Swap(totalCount, anotherCount); // 编译器生成 int 版 Swap
double memoryBlock = 3.14;
double dataChunk = 2.71;
Swap(memoryBlock, dataChunk); // 编译器生成 double 版 Swap
模板不占用栈或堆内存,它在编译期生成目标代码。
类型推演规则
int totalCount = 10;
double memoryBlock = 3.14;
// Swap(totalCount, memoryBlock); // 报错:T 无法推导为 int 或 double
模板拒绝隐式转换导致的歧义。
类模板
批量锻造法宝
传统做法需为每种物品建一个类。模板解法如下:
template<typename ItemType>
class Bag {
private:
ItemType* dataChunk;
size_t capacity;
size_t itemCount;
public:
Bag(size_t cap = 10) : capacity(cap), itemCount(0) {
dataChunk = new ItemType[capacity];
}
void addItem(const ItemType& item) {
if (itemCount < capacity) {
dataChunk[itemCount++] = item;
}
}
ItemType& getItem(size_t index) {
return dataChunk[index];
}
};
使用示例:
Bag<int> treasureBag(100);
Bag<std::string> talismanBag(50);
补充知识
编译期计算
模板支持编译期递归计算,如斐波那契数列:
template<int N> struct Fib {
static constexpr int value = Fib<N-1>::value + Fib<N-2>::value;
};
vector 陷阱
vector<bool> 是空间优化特化版(位压缩),operator[] 返回代理对象而非引用,使用时需注意。
核心要点
- 模板是蓝图,编译器按需生成具体版本;
typename T是占位符,直到传入实参才确定类型;- 类型推演拒绝妥协,宁可报错也不强转;
- 类模板用于批量定义通用数据结构。


