C++ Templates 04:不止传类型,还能传值——聊聊非类型模板参数
C Templates 04不止传类型还能传值——聊聊非类型模板参数Bilibili 同步视频一、类模板实战编译期定容量的栈使用这个栈⚠️一个超级容易踩的坑实例之间完全不兼容二、函数模板也能用非类型参数✨三、划重点非类型模板参数有严格的准入黑名单1. 浮点数不行2. 类对象不能直接塞进去3. 字符串字面量 “hello” 直接传不行四、总结回顾摘要提起 CC Templates 04不止传类型还能传值——聊聊非类型模板参数 模板绝大多数人第一反应都是templatetypename T用 T 来代表任意类型。但模板的能力远不止于此除了把类型当参数我们还能直接把编译期常量值塞进模板这就是「非类型模板参数」。用好它可以在编译阶段就完成一部分计算省去运行时的开销但它也有不少容易踩坑的语法陷阱今天我们结合实例把这套机制讲透。在日常写 C 代码的时候容器大小往往是运行时确定的。比如std::vector运行时动态分配内存灵活是灵活但免不了堆内存分配、释放的开销。那如果我们已经在写代码的时候就知道容器最大需要存多少元素能不能干脆用固定大小数组实现把容量交给编译器处理答案就是非类型模板参数。简单理解普通模板参数传的是「类型」而非类型模板参数传给模板的是一个编译期就确定的常量值。编译器拿到这个常量在实例化阶段直接生成对应版本代码全程不需要运行时参与天然拥有编译期优化的红利。Bilibili 同步视频C Templates 04不止传类型还能传值——聊聊非类型模板参数一、类模板实战编译期定容量的栈我们来实现一个栈。传统动态栈需要自己管理堆内存容易出现内存泄漏如果直接写死数组大小写T elems[100]容量写死太小会溢出太大又白白浪费内存。借助非类型模板参数我们把栈的最大容量变成模板的第二个参数让使用者在实例化的时候指定最大存储数量。#includestdexcept#includeiostream#includestring// T栈存储元素类型MAXSIZE非类型模板参数编译期常量代表栈最大容量templatetypenameT,intMAXSIZEclassStack{private:T elems[MAXSIZE];// 编译期确定大小的数组无堆内存开销intnumElems;// 当前栈内元素计数public:Stack():numElems(0){}voidpush(Tconstelem){if(numElemsMAXSIZE){throwstd::out_of_range(Stack::push(): stack is full);}elems[numElems]elem;numElems;}voidpop(){if(numElems0){throwstd::out_of_range(Stack::pop(): empty stack);}--numElems;}Ttop()const{if(numElems0){throwstd::out_of_range(Stack::top(): empty stack);}returnelems[numElems-1];}boolempty()const{returnnumElems0;}boolfull()const{returnnumElemsMAXSIZE;}};使用这个栈intmain(){try{Stackint,20int20Stack;// 最多容纳20个intStackint,40int40Stack;// 最多容纳40个intStackstd::string,40strStack;int20Stack.push(99);std::coutint20Stack.top()n;int20Stack.pop();strStack.push(Hello Template);std::coutstrStack.top()n;strStack.pop();// strStack.pop(); // 取消注释会抛出空栈异常}catch(std::exceptionconstex){std::cerr异常捕获ex.what()std::endl;}return0;}⚠️一个超级容易踩的坑实例之间完全不兼容Stackint,20和Stackint,40看着几乎一模一样仅仅是非类型参数MAXSIZE数值不一样但在编译器眼中这是两个完全无关的不同类型。下面这段代码直接编译报错Stackint,20s1;Stackint,40s2;s1s2;// ❌编译失败类型不一样不能赋值也不存在隐式转换性能小知识因为数组大小是编译期确定这个栈全程使用栈上数组没有 new/delete没有堆内存分配开销。代价是不同容量就会实例化出一份全新的类代码如果定义大量不同 MAXSIZE 的栈会带来模板代码膨胀。我们也可以给非类型模板参数设置默认值templatetypenameTint,intMAXSIZE100classStack{/* ... */};但实际开发不建议随便给默认参数。默认值应当贴合业务场景int、100这种通用默认值往往没什么实际意义不如让调用方显式指定代码可读性更高。二、函数模板也能用非类型参数✨不要以为非类型模板参数只属于类模板函数模板同样支持。我们可以把常量固化到函数内部编译期生成特化版本。举个例子写一个函数给传入的值加上一个编译期固定常量。templatetypenameT,intVALTaddValue(Tconstx){returnxVAL;}这里VAL就是函数模板的非类型参数。调用的时候addValueint,5(10)就得到 15相当于编译出一个固定 5 的函数。这个模板和 STL 算法搭配非常香比如std::transform批量对容器元素做运算。但是这里藏着一个经典 坑#includealgorithm#includevectorintmain(){std::vectorintsource{1,2,3,4};std::vectorintdest(4);// 错误写法直接传 addValueint,5 会编译报错// std::transform(source.begin(), source.end(), dest.begin(), addValueint,5);// ✅正确写法强制转换成函数指针std::transform(source.begin(),source.end(),dest.begin(),(int(*)(intconst))addValueint,5);return0;}为什么直接写会报错addValueint,5虽然我们只实例化了一份但编译器仍然把它看作重载函数集合。C 标准不允许直接把重载集合传入模板参数必须手动强转成具体函数指针类型。小道消息C 标准库工作组已经有提案希望消除这个别扭的强制转换未来版本的 C 有可能可以直接写但是现在写可移植代码还得老老实实加上转换。三、划重点非类型模板参数有严格的准入黑名单非类型模板参数听着很强但不是什么东西都能往里塞它对传入的实参有硬性约束✅允许传入整型常量、枚举值、拥有外部链接的指针 / 数组❌禁止传入浮点数、类对象、字符串字面量、内部链接的指针1. 浮点数不行templatedoubleVATdoublecalc(doublev){returnv*VAT;}// calc1.2(100); // ❌编译报错浮点数不能作为非类型模板实参虽然从技术实现角度现代编译器完全有能力支持浮点常量但出于历史标准原因C 目前不支持把浮点数作为模板非类型参数。2. 类对象不能直接塞进去#includestringtemplatestd::string Name// ❌报错类对象不允许classDemo{};3. 字符串字面量“hello”直接传不行templateconstchar*NameclassDemo{};Demohelloobj;// ❌报错字符串字面量属于内部链接对象字符串字面量在不同编译单元就算文字一模一样也是完全独立两份对象C 标准禁止拿来当模板实参。那如果我就想传字符串常量指针怎么办要用extern 外部链接全局字符数组templateconstchar*NameclassDemo{};// 外部链接全局字符数组externconstcharmyStr[]Hello C Template;DemomyStrobj;// ✅合法重点区分constchar*sabc;Demosobj2;// ❌依然错误s只是指针变量指向内部链接字符串字面量四、总结回顾C 模板分为类型模板参数typename T和非类型模板参数后者接收编译期常量值在编译阶段完成实例化很多场景可以规避运行时内存开销。同一个模板非类型参数数值不同生成完全不同的类型互相之间不能赋值转换也要留意模板实例代码膨胀风险。类模板、函数模板都支持非类型参数和 STL 算法配合的时候要留意重载函数集合带来的强制转换问题。参数有严格限制只接受整型、枚举、外部链接指针浮点数、普通类对象、字符串字面量都是黑名单成员踩了直接编译报错。拓展思考C17 之后新增了 auto 非类型模板参数templateauto N可以自动推导非类型参数的类型这又是另外一个有趣的知识点后续可以再聊聊。

相关新闻

LaTeX双栏跨栏浮动体放置问题与dblfloatfix宏包详解

LaTeX双栏跨栏浮动体放置问题与dblfloatfix宏包详解

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/5 8:40:17 阅读更多 →
Cursor插件加载失败根因解析:Web Boot机制与plugin.json契约

Cursor插件加载失败根因解析:Web Boot机制与plugin.json契约

1. 项目概述:从“plugins”这个词开始,我们到底在谈什么? “plugins”不是个新词,但最近它在开发者圈子里突然变得高频、烫手、甚至有点让人焦虑。你刷技术社区、看GitHub issue、翻Cursor官方文档,甚至只是随手搜一下…

2026/10/5 8:39:17 阅读更多 →
Ubuntu Realtek有线网卡驱动安装与Secure Boot签名实战

Ubuntu Realtek有线网卡驱动安装与Secure Boot签名实战

1. 为什么Ubuntu装有线网卡驱动这事总让人头疼——从“插上网线没反应”说起你刚把Ubuntu系统装好,兴冲冲插上网线,结果桌面右下角那个网络图标灰着,终端里ping 8.8.8.8直接报connect: Network is unreachable,ip a一看&#xff0…

2026/10/5 8:39:17 阅读更多 →

最新新闻

无线网络安全实验全流程:从抓包到防御的完整复现指南

无线网络安全实验全流程:从抓包到防御的完整复现指南

简介:这份《无线网络安全实验》PDF 面向信息安全、网络工程等专业的学生与实验指导教师,对应《信息系统安全技术及应用》课程中的「无线网络安全性研究与实践」实验项目,可用于课程实验报告撰写、实验流程复盘与安全技术入门练习。资源包内共…

2026/10/5 9:21:54 阅读更多 →
华为FusionSphere数据中心虚拟化部署实战:HA、热迁移与存储扩容避坑指南

华为FusionSphere数据中心虚拟化部署实战:HA、热迁移与存储扩容避坑指南

简介:这份华为数据中心虚拟化解决方案文档面向企业IT架构师、运维工程师及云计算学习者,围绕FusionSphere虚拟化技术,系统讲解如何整合计算、存储与网络资源,构建高可靠、可自动化运维的云数据中心。内容涵盖FusionCompute与Fusio…

2026/10/5 9:21:54 阅读更多 →
AI Agent执行循环设计指南:上下文、工具调用与状态管理

AI Agent执行循环设计指南:上下文、工具调用与状态管理

做了几年 LLM 应用之后,我有个越来越强烈的感受:一个 AI Agent 项目的上限由模型决定,下限却由执行循环决定。模型再强,如果 Agent Loop 设计得糙——上下文乱塞、状态丢三落四、循环停不下来——跑出来的效果依然没法看。反过来&…

2026/10/5 9:21:54 阅读更多 →
多Agent集群工程化实战:DeepAgents、MCP、A2A与Skills协同编排

多Agent集群工程化实战:DeepAgents、MCP、A2A与Skills协同编排

最近一年我大部分精力都花在一件事上:让一堆Agent在一个集群里好好协作,而不是各自为战。如果你正打算把单个Agent塞进真实业务,你会发现它在Demo里有多惊艳,到了生产环境就有多脆弱——工具调用一多就串线、上下文一长就丢状态、…

2026/10/5 9:21:54 阅读更多 →
Java住院管理系统源码解析:业务流程驱动的医疗信息化实践

Java住院管理系统源码解析:业务流程驱动的医疗信息化实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/5 9:21:54 阅读更多 →
安全岗位面试题怎么刷?从能力体检到数据驱动复习的工程化思路

安全岗位面试题怎么刷?从能力体检到数据驱动复习的工程化思路

简介:合集汇集了20余份HW(护网)面试题和近100份网络安全岗位面试题,覆盖天融信、长亭、安恒、奇安信、360等十余家厂商,适合安全服务、渗透测试、红队攻防、攻防研究员等方向的求职者,用于查漏补缺、巩固知…

2026/10/5 9:20:54 阅读更多 →

日新闻

马斯克杀回智能体战场,Grok 4.5万亿参数撑腰,Cursor接手数字白领项目:用TaoToken统一Key跑通多模型Agent工作流

马斯克杀回智能体战场,Grok 4.5万亿参数撑腰,Cursor接手数字白领项目:用TaoToken统一Key跑通多模型Agent工作流

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/5 0:00:22 阅读更多 →
AI编程工具插件机制详解:plugin.json配置与加载失败排查指南

AI编程工具插件机制详解:plugin.json配置与加载失败排查指南

1. 从“plugins”这个词说起:它到底在解决什么问题如果你最近在折腾 AI 编程工具,尤其是 Cursor、Codex CLI、Claude Code 这类带 CLI 的编辑器或命令行助手,那你大概率绕不开一个词——plugins。这个词本身不新鲜,从浏览器到 IDE…

2026/10/5 0:00:23 阅读更多 →
第26课:OpenClaw|日志审计与问题诊断:把日志链路改到 TaoToken 的排查清单

第26课:OpenClaw|日志审计与问题诊断:把日志链路改到 TaoToken 的排查清单

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/5 0:00:23 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/5 5:06:42 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/5 1:10:22 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/5 3:06:17 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 11:40:45 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 9:43:54 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 20:14:29 阅读更多 →