1.. 非类型模板参数
1.1 模板参数分两类:
类型模板参数(最常用):用 typename/class 声明,代表数据类型(如 int/string)
template <typename T> // T 是类型非类型模板参数:代表编译期常量值(数字、地址、指针等),不是类型,是具体的值
template <int SIZE> // SIZE 是一个整数常量非类型模板参数 = 模板里的常量,值在编译时就确定,不能改。
1.2.核心语法规则
声明在 template <> 中,直接写类型 + 变量名。
传入的必须是编译期常量(不能是运行时变量)。
不同的参数值 = 不同的模板实例(独立的类 / 函数)。
参数值是只读常量,不能修改。
2.类模板 + 非类型参数(固定大小数组)
#include <iostream> using namespace std; // T:类型模板参数 SIZE:非类型模板参数(整数常量) template <typename T, int SIZE> // 核心:非类型参数 class FixedArray { private: T arr[SIZE]; // 用编译期常量定义数组大小 public: // 获取固定大小 int getSize() const { return SIZE; } }; int main() { // 实例化:T=int,大小=5 FixedArray<int, 5> arr1; cout << arr1.getSize() << endl; // 输出 5 // 实例化:T=double,大小=10 FixedArray<double, 10> arr2; cout << arr2.getSize() << endl; // 输出 10 return 0; }3.函数模板 + 非类型参数
// 非类型模板参数 N:编译期常量 template <int N> int add(int x) { return x + N; } int main() { cout << add<10>(5) << endl; // 15 cout << add<20>(5) << endl; // 25 return 0; }template <>:模板声明关键字
int N:非类型模板参数
不是类型,是一个 编译期整数常量
调用时必须用 <值> 传入,且值在编译时就固定.
| 参数 | 类型 | 赋值时机 | 写法 |
|---|---|---|---|
N | 非类型模板参数 | 编译期 | add<10> |
x | 普通函数参数 | 运行期 | add(5) |
4.模板的特化
4.1、核心概念
模板特化是 C++ 模板的核心进阶知识点,简单说:给模板的「特定类型 / 特定参数」,单独写一套专属实现,覆盖通用模板。
默认模板是通用版(适配所有类型),特化模板是定制版(只适配指定类型 / 参数),调用时优先匹配定制版。
4.1.1. 为什么需要特化?
模板的通用代码无法适配所有场景,比如:
通用模板处理 int 正常,但处理指针 / 字符串 / 布尔值需要特殊逻辑;
非类型模板参数需要给特定常量单独实现。
4.1.2. 特化分类
全特化(完全特化):给所有模板参数指定具体值 / 类型,完全替换通用模板
✅ 函数模板 + 类模板 都支持
偏特化(部分特化):只给部分模板参数指定类型,保留部分通用
❌ 函数模板 不支持,仅类模板支持
4.2函数模板的全特化
#include <iostream> using namespace std; // 通用模板 template <typename T> T print(T val) { cout << "通用模板:" << val << endl; return val; } // 全特化:只针对 int 类型 template <> int print<int>(int val) { cout << "特化模板(int):数值是 " << val << endl; return val; } int main() { print("hello"); // 匹配通用模板 print(100); // 匹配 int 特化模板(优先) return 0; }4.3类模板的特化
4.3.1. 类模板全特化
#include <iostream> using namespace std; // 通用类模板 template <typename T> class Demo { public: void show() { cout << "通用类模板" << endl; } }; // 全特化:只为 double 类型定制 template <> class Demo<double> { public: void show() { cout << "特化类模板(double)" << endl; } }; int main() { Demo<int> d1; d1.show(); // 通用模板 Demo<double> d2; d2.show(); // 特化模板 return 0; }4.3.2类模板偏特化(部分特化)
// 通用模板(两个参数) template <typename T1, typename T2> class Test { public: void show() { cout << "通用双参数模板" << endl; } }; // 偏特化:T2 固定为 int,T1 仍通用 template <typename T1> class Test<T1, int> { public: void show() { cout << "偏特化:第二个参数是 int" << endl; } };