当前位置: 首页 > news >正文

C++模板特化:类型与常量的灵活掌控

一、模板参数再介绍初级模板知识模板参数是一个用来存放类型名称int double等内置类型和自定义类型名称的变量。在代码实现中使用模板参数写代码写一个函数或类会增加代码复用的能力。写出的函数或类被称为函数模板和类模板。 模板实例化编译器根据使用模板时指定的类型名称用这个类型名称来替代模板参数生成相应的函数或类。使用函数模板时通过传入参数类型实例化出相应的模板。 而使用类模板时需要显示说明模板参数类型才能实例化出相应的类。二、非类型模板参数前面提及的模板参数接受的都是类型的名字还有一种模板参数接受的是一个常数。看下面一段代码#includeiostreamtemplateclassT,size_t size10classarr{private:T arr[size];intlensize;public:arr();~arr();Toperator[](constarra);boolempty();};这个是CSTL中对数组的改造array的模拟实现未完成与c风格数组相比容器arr对越界访问更加严格。我们看到arr是一个类模板有两个模板参数第二个模板参数就是上面提及的非类型模板参数相当于C语言中常量的宏定义。但与宏定义相比较这样的类模板可以根据传入参数的不同自动调整常量不需要改变代码但是宏定义恰恰相反。举个arr的使用例子来体会非类型模板参数的用途#includeiostreamusingnamespacestd;#includearrayintmain(){arrayint,20arr{1,2,3,4,5};for(inti0;iarr.size();i){coutarr[i] ;//1 2 3 4 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0}coutendl;return0;}三、函数模板的特化为什么需要引入特化就函数模板而言由于所有符合函数模板的参数列表中的每组参数并不都要根据函数模板实例化出的函数进行运算总有一两个特例要实现不同的方法所以引入模板特化。比如我想实现一个函数当两个参数是一切参数时判断第一个参数是否大于第二个参数。如果这样实现#includeiostreamusingnamespacestd;templateclassTboolfun(T a,T b){returnab}intmain(){inta10,b20;int*pbb,*paa;coutfun(a,b)endl;coutfun(pa,pb)endl;}存在指针比较是不是没有任何意义当参数为int*时我们特化一个函数模板让它返回指针所指向的最大的数#includeiostreamusingnamespacestd;templateclassTboolfun(T a,T b){returnab}templateboolfunint*(int*a,int*b){return*a*b;}intmain(){inta10,b20;int*pbb,*paa;coutfun(a,b)endl;coutfun(pa,pb)endl;}函数模板特化的语法1.前提是有一个相关的函数模板2.在特化函数模板之前加上template3.在特化声明函数时在函数名之后参数表之前加上特化的类型名称4.要求函数的其余部分除将模板参数特化替代外必须和原来函数一模一样否则就会编译报错。函数模板特化的特点由于函数模板的性质当定义一个将函数模板中所有模板参数替代成统一类型名称的函数fun时调用一个既可以走函数模板又可以直接调用fun时编译器会不再实例化函数模板直接调用fun。因此函数模板特化的作用不大大多数情况都可以通过定义一个将函数模板中所有模板参数替代成统一类型名称的函数fun调用fun直接解决问题但也不排除只有使用函数模板特化的方法才能解决问题的项目。使用上面提及的第二种常规方法解决之前需要函数模板特化才可以解决的问题#includeiostreamusingnamespacestd;templateclassTboolfun(T a,T b){returnab;}boolfun(int*a,int*b){return*a*b;}intmain(){inta10,b20;int*pbb,*paa;coutfun(a,b)endl;coutfun(pa,pb)endl;}四、类模板的特化1.全特化顾名思义就是将所有参数都特化和函数模板特化一样这里也强调一下函数模板特化的方式只有一种类模板特化可以全特化也可以半特化。示例代码#includeiostreamusingnamespacestd;templateclassT1,classT2classc1{private:T1 t1;T2 t2;public:c1(){coutT1,T2endl;}};templateclassc1int,int{private:intt1;intt2;public:c1(){coutint ,int endl;}};intmain(){c1int,doublecc;c1int,intc1;//T1,T2//int, int}和函数模板特化一致特化定义前要加上template特化声明时l类的名字和{}之间要加上特化的类型名称2.半特化别称偏特化先来看一下半特化的代码演示#includeiostreamusingnamespacestd;templateclassT1,classT2classc1{private:T1 t1;T2 t2;public:c1(){coutT1,T2endl;}};templateclassT1classc1T1,int{private:T1 t1;intt2;public:c1(){coutT1 ,int endl;}};intmain(){c1int,doublecc;c1int,intc1;//T1,T2//T1, int}半特化和全特化的不同在于半特化定义之前加的是template未特化的模板参数声明特化时类名称和{}之间加的是未特化的模板参数特化的模板参数这个排序要求和类模板定义之前的模板参数声明要一一对应下面的例子就是最好的说明#includeiostreamusingnamespacestd;templateclassT1,classT2,classT3classc1{private:T1 t1;T2 t2;T3 t3;public:c1(){coutT1,T2,T3endl;}};templateclassT1,classT3classc1T1,int,T3{private:T1 t1;intt2;public:c1(){coutT1 ,int,T3 endl;}};intmain(){c1int,double,intcc;c1int,int,doublec1;/*T1, T2, T3 T1, int, T3*/}半特化还有一种特殊的例子当被特化的类未指针或引用时templateclassT1,classT2classData{public:Data(){coutDataT1, T2endl;}private:T1 _d1;T2 _d2;}//两个参数偏特化为指针类型templatetypenameT1,typenameT2classDataT1*,T2*{public:Data(){coutDataT1*, T2*endl;}private:T1 _d1;T2 _d2;};//两个参数偏特化为引用类型templatetypenameT1,typenameT2classDataT1,T2{public:Data(constT1d1,constT2d2):_d1(d1),_d2(d2){coutDataT1, T2endl;}private:constT1_d1;constT2_d2;};voidtest2(){Dataint,doubled2;// 调用基础的模板Dataint*,int*d3;// 调用特化的指针版本Dataint,intd4(1,2);// 调用特化的指针版本}
http://www.zskr.cn/news/1378013.html

相关文章:

  • Python通达信数据接口深度解析:构建高效金融数据获取系统
  • 百考通智能解析交叉学科,自动生成规范框架
  • 抖音批量下载技术解决方案:专业级自动化工具深度解析
  • 微博热搜爬虫实战:Selenium动态加载与反爬对抗
  • 专业级联发科设备解锁工具完全指南:深度解析mtkclient-gui核心功能与实战技巧
  • 如何用GetQzonehistory完整备份你的QQ空间记忆:终极免费指南
  • Word里优雅排版LaTeX公式?Aurora插件保姆级安装与配置指南(含CTeX套装)
  • 揭秘Topit:如何在macOS上实现300%效率提升的窗口置顶魔法?[特殊字符]
  • 嵌入式工程师在主流产品中的核心作用与角色定位分析
  • 2026最新版!Java面试“八股文+场景题”终极合集(囊括大厂考点+答案)
  • 避开Verilog状态机设计常见坑:从HDLbits Lemmings题目里学到的5个教训
  • 别再被Latch坑了!手把手教你用HDLbits案例彻底搞懂Verilog中的锁存器问题
  • FGO自动化战斗终极指南:如何用FGA彻底解放你的双手
  • 国产Jeep起死回生了?为啥要复活Jeep品牌?
  • 2026Q2湖北性价比高的财税公司排名推荐,十大正规资质齐全的财税机构优选指南 - 品牌智鉴榜
  • Switch控制器PC适配难题的技术解决方案:BetterJoy架构解析与高级配置指南
  • 3个关键步骤:解决macOS升级后Mac Mouse Fix鼠标侧键失效问题
  • RISC-V处理器模拟器深度解析:可视化架构设计与性能调优实战指南
  • 如果是无粘流体,还要考虑导热吗?——黏性和热传导本质同源:两者都来源于流体分子的微观热运动——黏性是分子热运动引发的动量交换,热传导则是分子热运动引发的能量交换。因此在传统近似中,忽略黏性的同时一般也
  • 10-系统技术架构师必备——AI智能架构与大模型应用
  • 福州黄金回收人气榜发布,福正美凭口碑拔得头筹 - 上门黄金回收
  • DeepSeek-R1 vs Qwen3 vs Llama3-70B:12项硬核基准测试结果对比,谁才是真正“性价比之王”?
  • 免费解锁网盘下载限速:LinkSwift网盘直链助手终极使用指南
  • 小学期学习报告-2
  • 2026 年针状肥四大品牌排名及解析 - 十大品牌榜
  • 跳槽简历评分总上不去?我用这AI工具,轻松搞定!
  • 福州黄金回收怎么选?福正美综合实力领跑 - 上门黄金回收
  • 百考通AI开题报告:贴合你的研究方向,一次成型
  • 百考通AI助你把教育理想转化为可行方案
  • 5步搞定游戏模组管理难题:KKManager终极完整指南