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

【C++】模板入门

本篇博客给大家带来的是C++的模板入门详解!

🐟🐟文章专栏:C++

🚀🚀若有问题评论区下讨论,我会及时回答

❤❤欢迎大家点赞、收藏、分享!


一、泛型编程

代码示例:

void swap(int& x, int& y)
{int tmp = x;x = y;y = tmp;
}void swap(double& x, double& y)
{double tmp = x;x = y;y = tmp;
}void swap(long& x, long& y)
{long tmp = x;x = y;y = tmp;
}

注意:由于交换数据的类型不同我们要写多个交换函数,带来的问题:代码复用率低,可维护性差,这时候我们提出了泛型编程。

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

模板:跟古代的印刷术差不多,模板分为:函数模板和类模板

二、函数模板

        函数模板:函数模板代表这一个函数家族,该函数和类型无关,在使用时被参数化,根据实参类型来产生函数的特定类型版本。

        1)书写方式:template<typename T,typename T2,。。。。,typename Tn>

        返回类型:函数名(参数列表){}

代码示例:

template<class T>//typename T这样也行,不能:struct T
void Swap(T& x, T& y)
{T tmp = x;x = y;y = tmp;
}int main()
{int a = 19;int b = 32;Swap(a, b);cout <<"a:"<< a <<' ' << "b:" << b;cout << endl;double c = 7;double d = 8;cout << "c:" << c <<" " << "d:" << d;cout << endl;return 0;
}

运行结果:

注意:在上面的代码中调用的是不同的函数,调用的是同一个模板,如:

调用Swap(a,b),模板会推演实例化出一个函数:

void swap(int& x, int& y)
{int tmp = x;x = y;y = tmp;
}

 调用Swap(c,d)也是一样:

void swap(double& x, double& y)
{double tmp = x;x = y;y = tmp;
}

模板的本质:我们本来要做的事交给编译器来做。

注意:实参参数不同,这时候会产生歧义,编译不通过,如:

template<class T>
void Swap(T& x, T& y)
{T tmp = x;x = y;y = tmp;
}int main()
{int a = 19;int b = 32;Swap(a, b);cout <<"a:"<< a <<' ' << "b:" << b;cout << endl;double c = 7;double d = 8;cout << "c:" << c <<" " << "d:" << d;cout << endl;Swap(a, c);//a是int类型,c是double类型,模板推演产生歧义return 0;
}

        2)隐式实例化和显示实例化

代码示例:

template<class T>
T Add(const T& x, const T& y)
{return x + y;
}int main()
{int a = 19;int b = 32;double c = 7;double d = 8;cout << Add(a, b) << endl;//隐式实例化cout << Add(a, (int)c) << endl;cout << Add<int>(a, b) << endl;//显示实例化cout << Add<int>(a, (int)c);return 0;
}

显示实例化的使用场景:

template<class T>
T* Fun(int n)
{T* ptr = new T[n];return ptr;
}int main()
{cout << Fun(10) << endl;//10传给了n,T是什么类型不知道,所以无法推演;正确写法:Fun<int>(10)告诉编译器T是int类型的return 0;
}

        3)模板参数的匹配原则

原则1:

代码示例1:

template<class T>
T Add(const T& x, const T& y)
{return x + y;
}int Add(int x, int y)
{return x + y;
}int main()
{Add(1, 2);//能不模板推演就不推演,直接调用我们自己写的Add函数return 0;
}

如果非要让模板来推演可以显示实例化来调用:

template<class T>
T Add(const T& x, const T& y)
{return x + y;
}int Add(int x, int y)
{return x + y;
}int main()
{Add(1, 2);//能不模板推演就不推演,直接调用我们自己写的Add函数Add<int>(1, 2);//调用模板return 0;
}

原则2:

代码示例2:

template<class T>
T Add(const T& x, const T& y)
{return x + y;
}int Add(int x, int y)
{return x + y;
}int main()
{Add(1, 1.1);//调用更匹配的,调用我们自己写的Add函数Add<int>(1, 1.1);//强行调用模板//显示实例化return 0;
}

三、类模板

        1、定义格式/书写方式

template<class T1,class T2....class Tn>
class+类模板名
{//类成员定义
};

         2、类模板的实例化

代码示例:

template<class T>
class Stack
{
public:Stack(int n=4){_a = new T[n];_top = _capaciyt = 0;}void Push(const T& x){}const T& Top(){return _a[_top - 1];}
private:T* _a;size_t _top;size_t _capacity;
};int main()
{Stack<int> s1;//解决C语言只能存储指定类型的数据Stack<double> s2;//类模板只能显示实例化return 0;
}

        3、类模板的声明和定义分离

代码示例:

template<class T>
class Stack
{
public:Stack(int n=4){_a = new T[n];_top = _capaciyt = 0;}void Push(const T& x);const T& Top(){return _a[_top - 1];}
private:T* _a;size_t _top;size_t _capacity;
};//声明和定义分离不建议到两个文件,处理起来麻烦
//所以一般写到同一个文件,如:
template<class T>//分离也要声明下面这行代码是类模板
void Stack<T>::Push(const T& x);int main()
{Stack<int> s1;//解决C语言只能存储指定类型的数据Stack<double> s2;//类模板只能显示实例化,Stack是类名,Stack<double>是类型return 0;
}

  

完!

http://www.dtcms.com/a/251857.html

相关文章:

  • python3.9成功安装nbextensions
  • [游戏实时地图] 地图数据 | 兴趣点数据 | 虚幻引擎SDK接口
  • 无人机指南
  • GO语言---panic和recover关键字
  • Mass框架
  • 面试题SpringCloud
  • GitHub又打不开了怎么办?git pull push失败怎么办?
  • Git开发流程
  • 自动驾驶系统研发系列—激光雷达干扰实战:自动驾驶安全的隐形陷阱
  • OpenHarmony 5.0 web组件输入法弹出导致闪现桌面或者多次操作卡主桌面现象
  • c++ 项目使用 prometheus + grafana 进行实时监控
  • 数据管道架构设计指南:5大模式与最佳实践
  • LG P4278 带插入区间K小值 Solution
  • Java的接口
  • 阿帕奇基金会软件授权与公司贡献者许可协议(中英双语版)
  • 基于CATIA轴系的最小边界曲面自动化生成技术深度解析
  • 力扣的SQL
  • 搭建基于 Prometheus、Grafana 和 Alertmanager 的监控告警系统
  • 「Linux文件及目录管理」文件内容的显示和处理类命令
  • 揭开MongoDB的神秘面纱:从陌生到初识
  • 如何修改PyCharm的界面颜色(超详细)
  • 手写简版React-router
  • 2025ICRA 最佳论文解读:麻省理工PolyTouch:一种多模态触觉传感器以及基于触觉扩散策略的接触丰富操作方法
  • 【学习笔记】深入理解Java虚拟机学习笔记——第9章 类加载及执行子系统的案例与实战
  • C语言进阶:深度解剖数据在内存中的存储(浮点型在内存中的存储)
  • Linux系统firewall-offline-cmd命令在企业网络安全防护中的应用案例分析
  • 2.RMII的时钟模式
  • Python训练营打卡 Day54
  • 【LangChain】5 评估
  • WebAssembly 2.0:超越浏览器的全栈计算革命