引言
在日常开发中,我们经常接触 函数参数,这是控制函数行为的最直接方式。但在 C++ 中还有一种强大的机制 —— 模板参数(Template Parameters),它赋予了我们在编译期就生成代码结构的能力。
本文将通过直观的类比,讲清楚模板参数和函数参数的区别,并深入介绍模板参数的主要类型与用途。
一、类比理解:模板参数 ≠ 函数参数
我们先看一个常见误解:
template<size_t V>
void foo() {std::array<int, V> arr; // V 决定数组大小
}
有些同学看到 会误以为这是函数参数,其实不然:
对比维度 | 模板参数 | 函数参数 (int v) |
---|---|---|
位置 | 在尖括号 < > 中 | 在圆括号 ( ) 中 |
生命周期 | 编译期 | 运行期 |
用途 | 控制代码生成(如数组大小、选择分支) | 控制函数逻辑/数据 |
可否参与模板实例化 | ✅ 是 | ❌ 否 |
是否可变 | ❌ 编译期固定 | ✅ 可动态变化 |
📌 举个例子更清楚:
// 模板参数:数组大小在编译期就确定
template<size_t N>
void printArray(std::array<int, N> arr) {for (auto x : arr) std::cout << x << " ";
}
这个 N 就是模板参数。如果你改成函数参数,就会出错:
// ❌ 错误示例:函数参数不能用于 std::array 定义
void printArray(int n, std::array<int, n> arr); // ❌ 错误,n不是编译期常量
二、模板参数的主要类型和用途
模板参数在 C++ 中可以大致分为以下几类,每一类都有对应的应用场景:
1️⃣ 类型模板参数 typename T / class T
template <typename T>
T add(T a, T b) { return a + b; }
- 用于泛型类型,如 int, float, std::string 等。
- 被广泛用于 STL 的容器与算法中。
2️⃣ 非类型模板参数(编译期常量)
template <int N>
std::array<int, N> makeArray() {return std::array<int, N>{};
}
- 可用于定义固定大小的数组、常量控制等。
- 类型包括:int, size_t, bool, 指针/引用常量等。
- 场景如:图着色、滑动窗口大小、缓存块大小、通道数量等。
三、何时使用模板参数?
🧩 你需要在编译期决定结构尺寸或逻辑分支
🔧 你想要类型安全的泛型结构
🚀 你追求运行效率和零运行时开销