非类型模板参数(NTTP)
- 非类型模板参数的核心概念
非类型模板参数是 C++ 模板的一种核心参数类型,与熟悉的类型模板参数(typename T/class T)相对:
-
- 类型模板参数:接收「类型」作为输入(如
int、std::string、自定义类); - 非类型模板参数:接收「编译期可确定的常量值」作为输入(如数字、指针、枚举值)。
- 类型模板参数:接收「类型」作为输入(如
一句话概括:类型模板参数传 “类型”,非类型模板参数传 “值”(且必须是编译期常量)。
基础语法:
// 非类型模板参数的声明格式:<类型 参数名> template <int N> // 整型非类型参数 template <const char* S> // 指针型非类型参数 template <HandlerType M> // 枚举型非类型参数(C++11+) template <auto V> // 自动推导型非类型参数(C++17+)
类型模板参数和非类型模板参数对比
#include <iostream> // 全局字符串常量(编译期存在,指针有效) constexpr const char kPath[] = "/progress"; // AcousticHandler 类(编译期地址) class AcousticHandler { public: // 进度更新处理函数 static void update_progress() { std::cout << "处理 /progress 接口请求" << std::endl; } }; //强类型枚举(编译器存在) enum class HttpMethod { GET, POST, PUT }; // 非类型参数 S:编译期字符串指针;HandlerFunc 函数地址;method 传枚举类型值 template <const char* Path,auto HandlerFunc,HttpMethod method> struct APIHolder { static constexpr const char* path = Path; // 固化为编译期常量 static constexpr auto func = HandlerFunc; static constexpr HttpMethod meth = method; }; //普通类模板 template <class PathT,class funcT,class methodT> struct NormalHolder{ PathT path; funcT func; methodT method; }; int main() { using Holder = APIHolder<kPath,AcousticHandler::update_progress,HttpMethod::GET>; std::cout << Holder::path << std::endl; // 直接读取,无运行时开销 Holder::func(); if(Holder::meth == HttpMethod::GET) { std::cout<<"处理Get请求"<<std::endl; } ////////////////////普通类模板//////////////// NormalHolder<const char*,void(*)(),HttpMethod> normal_api; normal_api.path = kPath; normal_api.method = HttpMethod::GET; normal_api.func = AcousticHandler::update_progress; return 0; }
输出结果
/progress 处理 /progress 接口请求 处理Get请求
2.表格总结
| 普通类模板参数 | 非类型参数 | |
| 输入内容 | 类型(如 int、std::string) |
编译期常量值(指针、地址、枚举值) |
| 语法声明 | template <typename T> | template <const char* Path> |
| 核心特性 | 泛化类型,运行时可赋值 | 固化值到编译期,运行时不可修改 |
| 错误检查阶段 | 类型不匹配时编译报错 | 值非法(如运行时变量)编译报错 |
| 内存 / 性能 | 成员是运行时变量,有赋值开销 | 成员是编译期常量,0 运行时开销 |
| 适用场景 | 通用容器(std::vector)、算法 |
固化常量配置(接口路径、函数地址) |

浙公网安备 33010602011771号