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

C++模板初阶,只需稍微学习;直接起飞;泛型编程

🤓泛型编程

  1. 假设像以前交换两个函数需要,函数写很多个或者要重载很多个;那么有什么办法实现一个通用的函数呢?
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(char& x, char& y)
{char tmp = x;x = y;y = tmp;
}
  1. 虽然函数重载可以实现,但是总归不太好
    1. 可以发现函数重载虽然可以使用同一个函数名,避免不了复用率比较低,假如有新的类型 还是需要再写对应类型函数
    2. 函数多了可维护性就会变差,一个出错可能其他的重载都会有问题
  2. 所以下面就用到了一个函数模板的,解决这个问题

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

🤓函数模板

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

☝️ 函数模板格式

template<typename T1,typename T2,...,typename Tn>

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

注意:typename是用来定义模板参数的关键字还可以写成class(但是不可以写成struct,不能使用struct来代替)

☝️ 函数模板的原理

  1. 函数模板是一个蓝图,本身就不是一个函数,编译器使用了某种方式产生特定具体类型函数的模具,所以本来需要写很多次函数重载的活或者其他重复的事情都交给了编译器
  2. 在编译器编译阶段,对于模板的使用,编译器需要根据传过来的实参类型来推导生成对应函数类型,提供调用;如int类型的实参使用函数模板时,编译器通过对应类型推演,推导出T类型是int类型,从而产生一份专门处理int类型的函数,对于double类型也是这样的;

虽然编译器麻烦一点,但是我们就可以少写一些了,岂不美哉

☝️ 函数模板的实例化

  1. 不同的类型使用函数模板时,这个过程称之为函数模板的实例化,函数模板的实例化分为两种:隐式实例化显式实例化
  2. 隐式模板实例化:通过传递的实参类型推导出对应函数的实际类型
template <class T>
void Swap(T& x, T& y)
{T tmp = x;x = y;y = tmp;
}template <typename Type1,typename Type2>
void fun(Type1& x,Type2& y)
{}
int main()
{int x1 = 10,x2 = 20;double y1 = 10.1,y2 = 20.1;Swap(x1, x2);Swap(y1, y2);//Swap(x1, y1); 这样就不行了,函数模板只写了一个T的关键字,必须是同一个类型cout << y1 << " " << y2 << endl;//C++自带的swap函数swap(x1, x2);swap(y1, y2);//如果两个参数不同,就需要有两个关键字fun(x1, y1);return 0;
}
  1. 显示实例化:
#include <iostream>
using namespace std;
template<class T>
T Add(const T& x, const T& y)//这里需要写const 不然不能使用强制转换
{return x + y;
}//可以写多个函数模板;如果不想强制转换和显示实例化可以写两个关键字的 
template<class T1,class T2>
T1 Add(T1& num1, T2& num2)
{return num1 + num2;
}template<class N>
N* apply(int x)//没有传入的实参类型,意思是的位置没有用到 N 推导不了
{N* tmp = new N[x];//N 用做了类型参数return tmp;
}int main()
{int su1 = 10, su2 = 20;double xu1 = 10.2, xu2 = 20.2;Add(su1, su2);Add(xu1, xu2);//隐式实例化; 强制类型转换cout << Add(su1,(int)xu1) << endl;cout << Add((double)su1,xu1) << endl;//显示实例化,直接告诉 T 的类型,编译器不需要推导了cout << Add<double>(su1,xu1)<< endl;//这里的su1 会有隐式类型转换cout << Add<int>(su1,xu1) << endl;cout << Add(su2, xu2) << endl;//这里必须显示写实例化double* space = apply<double>(20);//隐式类型转换不是想转就能转的,比如:指针,一般都是和int相关的类型char a = 'b';int ia = 2100;cout << (int)a << endl;cout << (char)ia << endl;return 0;
}
  1. 编译器一般不会自己进行隐式类型转换,怕出事
  2. 函数模板实例化,如果其他条件相同的情况下,会优先调用非模板函数;如果模板函数实例化出更好的,那么会选择模板;所以说什么好选择什么
  3. 函数模板对自定义类型不能隐式类型转换,对于普通的类型会自动隐式类型转换
#include <iostream>
using namespace std;
int Add(const int& x,const int& y) //这里优先调用
{return 20 * (x + y);
}template<class T>
T Add(const T& x, const T& y)//这里需要写const 不然不能使用强制转换
{return x + y;
}
int main()
{int su1 = 10, su2 = 20;Add(su1, su2);    
}

🤓类模板

☝️ 类模板的定义格式

template<class T1, class T2, ..., class Tn> 
class 类模板名
{// 类内成员定义
}; 
#include <iostream>
using namespace std;template<typename T>
class Stack
{
public:Stack(int n = 4):_array(new T[n])// T 就是代表的是模板实例化的类型, _size(0), _capacity(n){}void Push(const T& p);~Stack(){delete[] _array;_array = nullptr;_size = _capacity = 0;}
private:T* _array;size_t _size;size_t _capacity;
};template<typename T> //如果是声明和定义分离 就需要再写一个类模板
void Stack<T>::Push(const T& p)//告诉类中模板类型是什么
{if (_size == _capacity){T* tmp = new Stack[_capacity * 2];memcpy(tmp, _array, sizeof(T) * _size);//拷贝内容delete[] _array;//释放旧空间_array = tmp;_capacity = _capacity * 2;}_array[_size++] = p;
}int main()
{Stack<int> a1;return 0;
}
  1. 模板的定义和声明不建议放到两个不同的文件 .h 和 .cpp;会出现链接错误

☝️ 类模板的实例化

  1. 模板类是需要显示实例化的
  2. 和函数模板实例化不同,类模板的名字不是真正的类,而实例化的结果才是真正的类
int main()
{// Stack 是类名,Stack<int> 是类型Stack<int> a1;Stack<double> a2;return 0;
}

頑張ろ

相关文章:

C++模板初阶,只需稍微学习;直接起飞;泛型编程

&#x1f913;泛型编程 假设像以前交换两个函数需要&#xff0c;函数写很多个或者要重载很多个&#xff1b;那么有什么办法实现一个通用的函数呢&#xff1f; void Swap(int& x, int& y) {int tmp x;x y;y tmp; } void Swap(double& x, double& y) {doubl…...

【数据结构 | 红黑树】红黑树的性质和插入结点时的调整

文章目录 红黑树红黑树插入时的调整&#xff1f;1. 插入结点是根结点2. 插入结点的叔叔是红色3. 插入结点的叔叔是黑色LL 型RR型LR型RL型 红黑树 前提&#xff1a;二叉搜索树&#xff08;左 < 根 < 右&#xff09;—— 左根右根和**叶子&#xff08;NULL&#xff09;**都…...

mysql学习教程,从入门到精通,SQL导入数据(44)

1.SQL 导出数据 以下是一个关于如何使用 SQL 导出数据的示例。这个示例将涵盖从一个关系数据库管理系统&#xff08;如 MySQL&#xff09;中导出数据到 CSV 文件的基本步骤。 1.1、前提条件 你已经安装并配置好了 MySQL 数据库。你有访问数据库的权限。你知道要导出的表名。…...

【SpringAI】(二)让你的Java程序接入大模型——适合Java宝宝的大模型应用开发

开始之前&#xff0c;如果你对大模型完全没了解过&#xff0c;建议阅读之前的大模型入门文章&#xff1a; 【SpringAI】&#xff08;一&#xff09;从实际场景入门大模型——适合Java宝宝的大模型应用开发 那么今天就开始写一个基于Spring AI程序的HelloWord!将大模型接入到咱…...

音频剪辑在线工具 —— 让声音更精彩

你是否曾梦想过拥有自己的声音创作空间&#xff0c;却苦于复杂的音频编辑软件&#xff1f;接下来&#xff0c;让我们一同揭开这些音频剪辑在线工具的神秘面纱&#xff0c;看看它们如何帮助你实现从录音到发布的无缝衔接。 1.福昕音频剪辑 链接直达>>https://www.foxits…...

​http短连接和长连接​

参考短连接和长连接 短连接&#xff1a;客户端向服务器每进行一次Http操作&#xff0c;都需建立一次连接&#xff0c;任务完成后&#xff0c;断开连接&#xff1b;长连接&#xff1a;建立长连接后&#xff0c;传输数据的连接将不会中断&#xff0c;客户端每次访问服务器时都会…...

日志分析删除

日志分析 场景 运维嫌弃生产环境打印日志过多&#xff0c;而且日志存储需要费用&#xff0c;让我们减少打印日志大小&#xff0c;所以需要分析日志在哪里打印的过多 解决方案 读取生产日志文件&#xff0c;统计分析打印日志的地方&#xff0c;最后删除代码中打印日志的地方…...

DART: Implicit Doppler Tomography for Radar Novel View Synthesis 笔记

Link&#xff1a;https://wiselabcmu.github.io/dart/ Publish&#xff1a; 2024CVPR Abstract DART主要任务就是用来合成雷达距离多普勒图像range-droppler&#xff0c;可用于生成高质量的断层扫描图像。 Related Work 1 Radar Simulation 基于模型的方法 任务&#xff…...

redis-cli执行lua脚本

连接redis服务器命令 redis-cli -h 10.10.xx.xx -p 6380 -a password执行lua脚本传递KEY VALUE redis-cli -h 10.10.xx.xx -p 6380 -a password key1 key2 , arg1 arg2key和参数通过逗号分割&#xff0c;逗号前后必须有一个空格 如下执行lua脚本示例&#xff1a; -- script.…...

MySQL9的3个新特性

【图书推荐】《MySQL 9从入门到性能优化&#xff08;视频教学版&#xff09;》-CSDN博客 《MySQL 9从入门到性能优化&#xff08;视频教学版&#xff09;&#xff08;数据库技术丛书&#xff09;》(王英英)【摘要 书评 试读】- 京东图书 (jd.com) 本文讲解MySQL9的3个新特性&…...

《网络基础之 HTTP 协议:状态码含义全解析》

《网络基础之 HTTP 协议&#xff1a;状态码含义全解析》 在网络通信的浩瀚世界中&#xff0c;HTTP 协议犹如一座坚实的桥梁&#xff0c;连接着客户端与服务器。而其中的状态码&#xff0c;则是这座桥梁上的重要标识&#xff0c;为双方的交互提供了关键的反馈信息。 一、状态码…...

java真的正在越来越失去竞争力了吗

题记&#xff1a; java真的在越来越失去竞争力了吗&#xff1f;最近参加校招面试&#xff0c;过程中有问道java的问题&#xff0c;有的同学很直接了当&#xff08;或者是不假思索&#xff09;地说&#xff0c;java已经过时了吧&#xff0c;现在学java的人越来越少了。那么事实…...

【通过zip方式安装mysql服务】

通过zip方式安装mysql服务 Mysql安装包下载mysql安装及环境配置1.解压缩配置环境变量初始化mysql配置安装mysql服务启动MySQL服务连接mysql修改root用户密码 Mysql安装包下载 通过访问mysql官网下载&#xff1a;mysql下载地址 mysql安装及环境配置 1.解压缩 下载完成后&am…...

每日OJ题_WY3小易的升级之路_数学模拟_C++_Java

目录 牛客_WY3小易的升级之路_数学模拟 题目解析 C代码 Java代码 牛客_WY3小易的升级之路_数学模拟 小易的升级之路_牛客题霸_牛客网 (nowcoder.com) 描述&#xff1a; 小易经常沉迷于网络游戏.有一次,他在玩一个打怪升级的游戏,他的角色的初始能力值为 a.在接下来的一段…...

python xml的读取和写入

import xml.etree.ElementTree as ET from xml.dom import minidom# 读取XML文档 tree ET.parse("./xml_3/z_20240827_001.xml") root tree.getroot() # 获取size元素 size_find_0 root.find("size") # 获取width子元素 size_w size_find_0.find("…...

WebGL 小白入门学习

1. WebGL是什么&#xff1f; WebGL&#xff08;Web Graphics Library&#xff09;是一种JavaScript API&#xff0c;它允许你在不需要安装任何额外插件的情况下&#xff0c;直接在浏览器中渲染高性能的2D和3D图形。WebGL利用了用户的图形处理单元&#xff08;GPU&#xff09;来…...

OSI七层协议

OSI&#xff08;Open System Interconnection&#xff09;七层协议&#xff0c;即开放式系统互联参考模型&#xff0c;是一个由国际标准化组织&#xff08;ISO&#xff09;提出的用于描述计算机网络中通信的结构和功能的理论模型。它将网络通信过程分为七个层次&#xff0c;每个…...

超平面(Hyperplane)和半空间(Halfspace)

文章目录 一、超平面&#xff08;Hyperplane&#xff09;1. 定义2. 超平面的方程3. 例子4. 超平面的性质 二、半空间&#xff08;Halfspace&#xff09;1. 定义2. 半空间的表示3. 半空间的性质 三、超平面与半空间的关系四、应用1. 线性规划2. 机器学习3. 计算几何4. 凸分析 五…...

TCP(Transmission Control Protocol,传输控制协议)整理

TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;是一种面向连接的、可靠的传输协议&#xff0c;它是OSI&#xff08;Open System Interconnection&#xff0c;开放式系统互联&#xff09;模型中的第四层协议&#xff0c;通常使用于网络中的…...

R语言绘制线性回归图

线性回归图以二维坐标系展示两个变量关系。数据点代表实际观测值&#xff0c;核心是线性回归线。此线通过统计方法确定&#xff0c;与数据点距离平方和最小。它反映变量间线性趋势&#xff0c;斜率正负决定相关方向。可用于预测因变量值&#xff0c;也能进行推断统计。在数据分…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查

在对接支付宝API的时候&#xff0c;遇到了一些问题&#xff0c;记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...

OpenLayers 分屏对比(地图联动)

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能&#xff0c;和卷帘图层不一样的是&#xff0c;分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

return this;返回的是谁

一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请&#xff0c;不同级别的经理有不同的审批权限&#xff1a; // 抽象处理者&#xff1a;审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...

Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)

引言 工欲善其事&#xff0c;必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后&#xff0c;我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集&#xff0c;就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...

OD 算法题 B卷【正整数到Excel编号之间的转换】

文章目录 正整数到Excel编号之间的转换 正整数到Excel编号之间的转换 excel的列编号是这样的&#xff1a;a b c … z aa ab ac… az ba bb bc…yz za zb zc …zz aaa aab aac…; 分别代表以下的编号1 2 3 … 26 27 28 29… 52 53 54 55… 676 677 678 679 … 702 703 704 705;…...

Java数组Arrays操作全攻略

Arrays类的概述 Java中的Arrays类位于java.util包中&#xff0c;提供了一系列静态方法用于操作数组&#xff08;如排序、搜索、填充、比较等&#xff09;。这些方法适用于基本类型数组和对象数组。 常用成员方法及代码示例 排序&#xff08;sort&#xff09; 对数组进行升序…...

高端性能封装正在突破性能壁垒,其芯片集成技术助力人工智能革命。

2024 年&#xff0c;高端封装市场规模为 80 亿美元&#xff0c;预计到 2030 年将超过 280 亿美元&#xff0c;2024-2030 年复合年增长率为 23%。 细分到各个终端市场&#xff0c;最大的高端性能封装市场是“电信和基础设施”&#xff0c;2024 年该市场创造了超过 67% 的收入。…...

分布式计算框架学习笔记

一、&#x1f310; 为什么需要分布式计算框架&#xff1f; 资源受限&#xff1a;单台机器 CPU/GPU 内存有限。 任务复杂&#xff1a;模型训练、数据处理、仿真并发等任务耗时严重。 并行优化&#xff1a;通过任务拆分和并行执行提升效率。 可扩展部署&#xff1a;适配从本地…...

短视频时长预估算法调研

weighted LR o d d s T p 1 − p ( 1 − p ) o d d s T p ( T p o d d s ∗ p ) o d d s p o d d s T o d d s odds \frac{Tp}{1-p} \newline (1-p)odds Tp \newline (Tp odds * p) odds \newline p \frac{odds}{T odds} \newline odds1−pTp​(1−p)oddsTp(Tpodds…...