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

初阶模板(C++)

1. 泛型编程

正常实现一个通用的交换函数如下

//----泛型编程--- void Swap(int& left, int& right) { int temp = left; left = right; right = temp; } void Swap(double& left, double& right) { double temp = left; left = right; right = temp; } void Swap(char& left, char& right) { char temp = left; left = right; right = temp; }

使用函数重载虽然可以实现,但是有一下几个不好的地方:
1. 重载的函数仅仅是类型不同,代码复用率比较低,只要有新类型出现时,就需要用户自己增
加对应的函数
2. 代码的可维护性比较低,一个出错可能所有的重载均出错
那能否告诉编译器一个模子,让编译器根据不同的类型利用该模子来生成代码呢?.
如果在C++中,能够存在这样一个模具,通过给这个模具中填充不同材料(类型),来获得不同
材料的铸件(即生成具体类型的代码),那将会节省许多头发

泛型编程:编写与类型无关的通用代码,是代码复用的一种手段。模板是泛型编程的基础

2.模板

模板 分为函数模板和类模板

1.函数模板

函数模板概念
函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生
函数的特定类型版本。
函数模板格式
template<typename T1, typename T2,......,typename Tn>
返回值类型 函数名(参数列表){}

template<typename T> void Swap( T& left, T& right) { T temp = left; left = right; right = temp; }

注意:typename是用来定义模板参数关键字,也可以使用class(切记:不能使用struct代替
class)

函数模板的原理
函数模板是一个蓝图,它本身并不是函数,是编译器用使用方式产生特定具体类型函数的模具。
所以其实模板就是将本来应该我们做的重复的事情交给了编译器在编译器编译阶段,对于模板函数的使用,编译器需要根据传入的实参类型来推演生成对应类型的函数以供调用。比如:当用double类型使用函数模板时,编译器通过对实参类型的推演,将T确定为double类型,然后产生一份专门处理double类型的代码,对于字符类型也是如此。

函数模板的实例化
用不同类型的参数使用函数模板时,称为函数模板的实例化。模板参数实例化分为:隐式实例化
和显式实例化。

1. 隐式实例化:让编译器根据实参推演模板参数的实际类型

2. 显式实例化:在函数名后的<>中指定模板参数的实际类型

//---函数模板的隐式实例化---让编译器根据实参推演模板参数的实际类型 template <typename T> T Add(const T& left,const T& right) { return left + right + 10; } //int Add(const int left, const int right) //{ // return left + right; //} int main() { int a = 10, b = 33; Swap(a, b);//---函数模板的隐式实例化 double x = 10.2, y = 10.3;//如果类型不匹配,编译器会尝试进行隐式类型转换,如果无法转换成功编译器将会报错 Add(a, (int)y);//若存在普通函数则会进入普通函数进行强制类型转化丢失精度值 无则需要自己强转所需类型 Add<double>(x, b);//---函数模板的显式实例化 return 0; }

模板参数的匹配原则

//函数匹配原则1. 一个非模板函数可以和一个同名的函数模板同时存在,而且该函数模板还可以被实例化为这个非模板函数
//函数匹配原则2.对于非模板函数和同名函数模板,如果其他条件都相同,在调动时会优先调用非模板函数而
//不会从该模板产生出一个实例。如果模板可以产生一个具有更好匹配的函数, 那么将选择模板
//函数匹配原则3. 模板函数不允许自动类型转换,但普通函数可以进行自动类型转换

2.类模板

类模板的定义格式

//template<class T1, class T2,class Tn> //class 类模板名 //{ // // 类内成员定义 //};
#include<iostream> using namespace std; // 类模版 template<typename T> class Stack { public: Stack(size_t capacity = 4) { _array = new T[capacity]; _capacity = capacity; _size = 0; } void Push(const T& data); private: T* _array; size_t _capacity; size_t _size; }; // 模版不建议声明和定义分离到两个文件.h 和.cpp会出现链接错误 template<class T> void Stack<T>::Push(const T& data) { // 扩容 _array[_size] = data; ++_size; } int main() { Stack<int> st1; // int-----就是用一段栈的代码得到实例化可以存储不同类型的栈空间栈对象 Stack<double> st2; // double //类模板实例化与函数模板实例化不同,类模板实例化需要在类模板名字后跟<>, //然后将实例化的 //类型放在<>中即可,类模板名字不是真正的类,而实例化的结果才是真正的类。 return 0; }

类模板的实例化
类模板实例化与函数模板实例化不同,类模板实例化需要在类模板名字后跟<>,然后将实例化的
类型放在<>中即可,类模板名字不是真正的类,而实例化的结果才是真正的类。 具体见上面代码

3.我的gitee

https://gitee.com/jiangmingpeng0716/c-learning-process

http://www.jsqmd.com/news/765670/

相关文章:

  • 3个必学Xournal++数字笔记技巧:从PDF批注到专业绘图
  • 别再只盯着阻抗了!FR4板材的损耗角正切(Df)如何悄悄吃掉你的高速信号?
  • ColabFold:让蛋白质结构预测变得简单高效的神器
  • 手把手教你用Simulink搞定Boost PFC电流环:从扫频到PI参数整定(附避坑指南)
  • 独立开发者如何通过Taotoken管理多个项目的AI密钥与权限
  • WHEELTEC N100 AHRS模块调平校准避坑指南:告别姿态角漂移与数据偏差
  • GetQzonehistory:一站式自动化备份QQ空间历史说说的智能开源工具
  • todg6.ocx文件丢失无法启动程序解决
  • 从用量看板观测API调用延迟与token消耗的日常波动
  • 风电仿真避坑指南:Matlab画功率曲线时,你的Cp公式用对了吗?
  • 《龙虾OpenClaw系列:从嵌入式裸机到芯片级系统深度实战60课》013、ADC与DAC:模拟信号采集与转换的硬件细节
  • 2026年浙江成人高考培训机构口碑排行,哪家靠谱值得选? - 浙江教育测评
  • 互联网大厂 Java 求职面试实战:从基础到微服务的精彩对话
  • BetterNCM安装器:如何让你的网易云音乐变得更好用?
  • 五一假期最后一天,还要补作业
  • AI 英语伴学 APP 的开发费用
  • 宿舍6人用免费试用降AIGC率:拼单方案完整复盘记录! - 我要发一区
  • Fan Control终极指南:5步打造完美的Windows风扇控制系统
  • 从双非到985:避开CS保研材料关的3个隐形陷阱(附真实案例复盘)
  • 如何构建Windows任务栏图标居中解决方案的安全加固与自动化检测体系
  • QRazyBox:三步修复损坏二维码的终极免费工具
  • 用Cityscapes预训练模型搞定KITTI语义分割:DeepLabv3+ (PyTorch) 实战避坑指南
  • vue基于springboot的旅游信息分享管理平台 旅游门票酒店预订系统
  • 从Windows迁移到Linux?保姆级教程:在Ubuntu/CentOS上安装配置Serv-U 15.4管理后台
  • RAG高级技巧
  • 用了有机肉桂后,我家厨房彻底变了样
  • 通过用量看板清晰观测 Taotoken 上各模型的调用成本与消耗
  • 手把手教你用HC-04蓝牙模块和串口助手,完成第一次无线数据传输(附AT指令详解)
  • 这些免费降AI工具千万别用:5类伪免费套路用户曝光警示! - 我要发一区
  • 华为AC旁挂三层组网实战:手把手教你配置直接转发与无缝漫游(附完整命令)