C++模板
模板是泛型编程的基础,泛型编程即以一种独立于任何特定类型的方式编写代码。模板的目的是为了提高复用性,将类型参数化,函数模板作用:建立一个通用函数,其函数返回值类型和形参类型可以不具体制定,用一个虚拟的类型来代表。
例如:
交换整形函数和交换浮点型函数在不使用模板的情况下,需要定义两次函数,但我们发现函数中除了函数名和变量类型外,其他代码均相同。那有没有一种办法可以只定义一次函数,实现这类型的交换函数呢?答案是有,用模板
template<typename T>//函数声明或定义
template --- 声明创建模板
typename --- 表面其后面的符号是一种数据类型,可以用class代替
T --- 通用的数据类型,名称可以替换,通常为大写字母
#include <iostream>
using namespace std;//交换整型函数
void swapInt(int& a, int& b) {int temp = a;a = b;b = temp;
}//交换浮点型函数
void swapDouble(double& a, double& b) {double temp = a;a = b;b = temp;
}//利用模板提供通用的交换函数
template<typename T>
void mySwap(T& a, T& b)
{T temp = a;a = b;b = temp;
}void test01()
{int a = 10;int b = 20;//swapInt(a, b);//利用模板实现交换//1、自动类型推导//mySwap(a, b);//2、显示指定类型mySwap<int>(a, b);cout << "a = " << a << endl;cout << "b = " << b << endl;}int main() {test01();system("pause");return 0;
}

在上述代码中,模板函数mySwap()可以使用两种方法完成数据类型的指定
1.自动类型推导
mySwap(a,b);
编译器根据我们传入的a,b类型来确认数据类型
2.显示指定类型
mySwap<数据类型>(a,b);
(注意事项:1.自动类型推导,必须推导出一致的数据类型T,才可以使用
2.模板必须要确定出T的数据类型,才可以使用 )
案例:
利用函数模板封装一个排序的函数,可以对不同数据类型数组进行排序
排序规则从大到小,排序算法为选择排序
分别利用char数组和int数组进行测试
#include<iostream>
using namespace std;
template<class T>
//交换函数模板
void mySwap(T& a, T& b)
{T temp = a;a = b;b = temp;
}
//排序算法
template<class T>
void mySort(T arr[],int len)
{for (int i = 0; i < len; i++){int max = i;//认定最大值下标for (int j = i + 1; j < len; j++){//认定的最大值 比遍历出的数值要小,说明j下标的元素才是真正的最大值if (arr[max] < arr[j]){max = j;}}if (max != i){//交换max和i元素mySwap(arr[max], arr[i]);}}
}//提供打印数组模板
template<typename T>
void printArray(T arr[], int len) {for (int i = 0; i < len; i++) {cout << arr[i] << " ";}cout << endl;
}
void test01()
{//测试char数组char charArr[] = "badcfekb";int num = sizeof(charArr) / sizeof(char);mySort(charArr, num);printArray(charArr, num);
}void test02()
{//测试int数组int intArr[] = { 3,2,7,9,4,6,8,0 };int num = sizeof(intArr) / sizeof(int);mySort(intArr, num);printArray(intArr, num);
}int main()
{test01();test02();system("pause");return 0;}
运行结果如下:

说明我们写的模板可以对不同数据类型数组进行排序
普通函数和函数模板的区别:
普通函数调用时可以发生自动类型转换(隐式类型转换)
函数模板调用时,如果利用自动类型推导,不会发生隐式类型转换
如果利用显示指定类型的方式,可以发生隐式类型转换
隐式类型转换:若参与运算量的类型不同,则先转换成同一类型,然后进行运算。
int和char类型的数据使用函数模板时
//普通函数
#include<iostream>
using namespace std;
int myAdd01(int a, int b)
{return a + b;
}//函数模板
template<class T>
T myAdd02(T a, T b)
{return a + b;
}//使用函数模板时,如果用自动类型推导,不会发生自动类型转换,即隐式类型转换
void test01()
{int a = 10;int b = 20;char c = 'c';//myAdd02(a, c); // 报错,使用自动类型推导时,不会发生隐式类型转换myAdd02<int>(a, c); //正确,如果用显示指定类型,可以发生隐式类型转换cout << myAdd01(a, c) << endl; //正确,将char类型的'c'隐式转换为int类型 'c' 对应 ASCII码 99}int main() {test01();system("pause");return 0;
}

普通函数和函数模板的调用规则:
1. 如果函数模板和普通函数都可以实现,优先调用普通函数
2. 可以通过空模板参数列表来强制调用函数模板
3. 函数模板也可以发生重载
4. 如果函数模板可以产生更好的匹配,优先调用函数模板
#include<iostream>
using namespace std;void myPrint(int a, int b)
{cout << "调用的普通函数" << endl;
}template<typename T>
void myPrint(T a, T b)
{cout << "调用的模板" << endl;
}template<typename T>
void myPrint(T a, T b, T c)
{cout << "调用重载的模板" << endl;
}void test01()
{//1、如果函数模板和普通函数都可以实现,优先调用普通函数// 注意 如果告诉编译器 普通函数是有的,但只是声明没有实现,或者不在当前文件内实现,就会报错找不到int a = 10;int b = 20;myPrint(a, b); //调用普通函数//2、可以通过空模板参数列表来强制调用函数模板myPrint<>(a, b); //调用函数模板//3、函数模板也可以发生重载int c = 30;myPrint(a, b, c); //调用重载的函数模板//4、 如果函数模板可以产生更好的匹配,优先调用函数模板char c1 = 'a';char c2 = 'b';myPrint(c1, c2); //调用函数模板
}int main() {test01();system("pause");return 0;
}

模板的局限性:
模板的通用性并不是万能的
template<class T>
void f(T a, T b)
{a = b;
}
在上述代码中提供的赋值操作,如果传入的a和b是一个数组,就无法实现了
#include<iostream>
using namespace std;#include <string>class Person
{
public:Person(string name, int age){this->m_Name = name;this->m_Age = age;}string m_Name;int m_Age;
};//普通函数模板
template<class T>
bool myCompare(T& a, T& b)
{if (a == b){return true;}else{return false;}
}//具体化,显示具体化的原型和定意思以template<>开头,并通过名称来指出类型
//具体化优先于常规模板
template<> bool myCompare(Person& p1, Person& p2)
{if (p1.m_Name == p2.m_Name && p1.m_Age == p2.m_Age){return true;}else{return false;}
}void test01()
{int a = 10;int b = 20;//内置数据类型可以直接使用通用的函数模板bool ret = myCompare(a, b);if (ret){cout << "a == b " << endl;}else{cout << "a != b " << endl;}
}void test02()
{Person p1("Tom", 10);Person p2("Tom", 10);//自定义数据类型,不会调用普通的函数模板//可以创建具体化的Person数据类型的模板,用于特殊处理这个类型bool ret = myCompare(p1, p2);if (ret){cout << "p1 == p2 " << endl;}else{cout << "p1 != p2 " << endl;}
}int main() {test01();test02();system("pause");return 0;
}
利用具体化的模板,可以解决自定义类型的通用化,如果不用具体化的模板,系统软件将无法编译自定义类型
相关文章:
C++模板
模板是泛型编程的基础,泛型编程即以一种独立于任何特定类型的方式编写代码。模板的目的是为了提高复用性,将类型参数化,函数模板作用:建立一个通用函数,其函数返回值类型和形参类型可以不具体制定,用一个虚…...
【JavaEE】HTML基础知识
目录 1.HTML结构 2.HTML常见标签 3.表格标签 4.列表标签 5.表单标签 6.select 标签 7.textarea 标签 8.无语义标签: div & span 9.标签小练习 1.HTML结构 形如: <body idmyId>hello</body> HTML的书写格式 标签名 (body) 放到 <…...
mysql与redis区别
一、.redis和mysql的区别总结 (1)类型上 从类型上来说,mysql是关系型数据库,redis是缓存数据库 (2)作用上 mysql用于持久化的存储数据到硬盘,功能强大,但是速度较慢 redis用于存储使…...
Hive本地开发/学习环境配置
前提 hive依赖hadoop的相关组件,需要启动Hadoop的相关组件。 Hive 版本:3.1.3 Hadoop版本:3.3.4 hive-env.sh export HADOOP_HOME$HADOOP_HOME export HIVE_CONF_DIR/usr/local/Cellar/hive/3.1.3/libexec/conf export HIVE_AUX_JARS_PATH/…...
《基于EPNCC的脉搏信号特征识别与分类研究》阅读笔记
目录 一、论文摘要 二、论文十问 三、论文亮点与不足之处 四、与其他研究的比较 五、实际应用与影响 六、个人思考与启示 参考文献 一、论文摘要 为了快速获取脉搏信号的完整表征信息并验证脉搏信号在相关疾病临床诊断中的敏感性和有效性。在本文中,提出了一…...
Linux下解压和压缩命令大全(详解+案例)
linux常用的解压和压缩命令如下: .zip或.zipx 压缩文件.zip、.zipx:都可以使用zip命令。例如,要将目录/home/user1/mydata压缩成一个文件mydata.zip,可以使用以下命令: zip -r mydata.zip /home/user1/mydata/要解压…...
Linux的常用指令
重启 init 6或reboot 关机 init 0 或halt如果没有执行关机命令,强制断电或关闭本地虚拟机的窗口,会导致Linux操作系统文件的损坏,严重的可能导致系统无法正常启动。 清屏 clear 查看服务器的ip地址 ip addr 时间操作 普通用户可以查看时间&am…...
第 5 章 HBase 优化
5.1 RowKey 设计 一条数据的唯一标识就是 rowkey,那么这条数据存储于哪个分区,取决于 rowkey 处于 哪个一个预分区的区间内,设计 rowkey的主要目的 ,就是让数据均匀的分布于所有的 region 中,在一定程度上防止数据倾斜…...
台北房价预测
目录 1.数据理解1.1分析数据集的基本结构,查询并输出数据的前 10 行和 后 10 行1.2识别并输出所有变量 2.数据清洗2.1输出所有变量折线图2.2缺失值处理2.3异常值处理 3.数据分析3.1寻找相关性3.2划分数据集 4.数据整理4.1数据标准化 5.回归预测分析5.1线性回归&…...
9:00进去,9:05就出来了,这问的也太···
从外包出来,没想到死在另一家厂子了。 自从加入这家公司,每天都在加班,钱倒是给的不少,所以也就忍了。没想到8月一纸通知,所有人不许加班,薪资直降30%,顿时有吃不起饭的赶脚。 好在有个兄弟内推…...
debootstrap 构建 RISC-V 64 Ubuntu 根文件系统
debootstrap 构建 Ubuntu RISC-V Linux 根文件系统 flyfish 主机信息 命令 lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 20.04.6 LTS Release: 20.04 Codename: focal制作的根文件系统为 RISC-V 64 Ubuntu 22.04 LTS 1 主机…...
腾讯云轻量应用服务器(Lighthouse)怎么样?
轻量应用服务器是否好用,小白这么多年的经验来看,跑企业站或博客都没问题,因为小流量站是可以的。但是限制流量的服务器只适合小站。超流量后是要扣费的。简而言之,超过流量是按流量计费的。如果被攻击大概率会欠费。如果是企业用…...
学习 AI 常用的一些专业词汇
学习 AI 常用的一些专业词汇 AI 词汇集 AI 词汇集 神经网络(Neural Network): 由节点(模型参数)和连接(权重)组成的网络结构,用于机器学习与深度学习。 深度学习(Deep Learning): 使用包含多隐藏层神经网络进行表征学习的机器学习方法。 机器学习(Machine Learnin…...
IP协议基础
文章目录 基本概念IP和TCP分别解决什么问题 以下过程都是在网络层完成的网段划分路由路由转发过程路由表 基本概念 主机: 配有IP地址, 但是不进行路由控制的设备。 路由器: 即配有IP地址, 又能进行路由控制。 节点: 主机和路由器的统称。 IP和TCP分别解决什么问题 TCP解决…...
Redis主从复制、哨兵实战
环境:linux centos7.x ,虚拟机3台 版本:redis-6.2.6 1.下载安转redis 下载地址 wget https://download.redis.io/releases/redis-6.2.6.tar.gz解压 tar -zxvf redis-6.2.6.tar.gz移动目录 mv redis-6.2.6 /usr/local/redis编译 cd /usr/…...
README.md编写
一、摘要 项目一般会有个描述文件,对于项目的代码来讲,这个描述就是README.md文件,可以描述各模块功能、目录结构等。该文件可以方便让人快速了解项目的代码结构和功能。当然,若要深层次的了解项目,就得看项目总体的需…...
软件设计证书倒计时28天
从一个月前的果断报考软件设计证书,我没有后悔过。 软件设计证书一个月备考情况: 现在做选择题的正确率可以达到65%。是重复做过两遍历年真题。 接下来是继续做模拟题。 大题的题型基本是都知道, 第一题数据流图,第二题er图&…...
程序员基础的硬件知识(cpu、主板、显卡、内存条等)
一、综合简介 cpu:负责运算数据,就等于你的大脑运算速度。 显卡:本来没有显卡,后来因为大家对图片要求越来越高,视频要求越来越高,啥都让cpu算太累了,于是分出来一个,专门用来计算…...
优化Google Cloud Storage大文件上传和内存溢出
背景 我们的项目每天都会并行上传好几万份文件到下游的GCP Cloud Storage,当文件比较大时,会采用GCP的可续上传方案,通过把文件切分成多个数据块,分多次HTTP请求上传到GCP Bucket,具体可参考https://cloud.google.com…...
chatGPT的prompt技巧
Prompt 公式是 Prompt 的特定格式,通常由三个主要元素组成: 任务:明确而简洁地陈述 Prompt 要求模型生成的内容。指令:模型在生成文本时应遵循的指令。角色:模型在生成文本时应扮演的角色。 指令 Prompt 技术 指令 …...
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...
Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
大型活动交通拥堵治理的视觉算法应用
大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动(如演唱会、马拉松赛事、高考中考等)期间,城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例,暖城商圈曾因观众集中离场导致周边…...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...
uniapp 开发ios, xcode 提交app store connect 和 testflight内测
uniapp 中配置 配置manifest 文档:manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号:4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...
第八部分:阶段项目 6:构建 React 前端应用
现在,是时候将你学到的 React 基础知识付诸实践,构建一个简单的前端应用来模拟与后端 API 的交互了。在这个阶段,你可以先使用模拟数据,或者如果你的后端 API(阶段项目 5)已经搭建好,可以直接连…...
Java并发编程实战 Day 11:并发设计模式
【Java并发编程实战 Day 11】并发设计模式 开篇 这是"Java并发编程实战"系列的第11天,今天我们聚焦于并发设计模式。并发设计模式是解决多线程环境下常见问题的经典解决方案,它们不仅提供了优雅的设计思路,还能显著提升系统的性能…...
2.2.2 ASPICE的需求分析
ASPICE的需求分析是汽车软件开发过程中至关重要的一环,它涉及到对需求进行详细分析、验证和确认,以确保软件产品能够满足客户和用户的需求。在ASPICE中,需求分析的关键步骤包括: 需求细化:将从需求收集阶段获得的高层需…...
GeoServer发布PostgreSQL图层后WFS查询无主键字段
在使用 GeoServer(版本 2.22.2) 发布 PostgreSQL(PostGIS)中的表为地图服务时,常常会遇到一个小问题: WFS 查询中,主键字段(如 id)莫名其妙地消失了! 即使你在…...
职坐标物联网全栈开发全流程解析
物联网全栈开发涵盖从物理设备到上层应用的完整技术链路,其核心流程可归纳为四大模块:感知层数据采集、网络层协议交互、平台层资源管理及应用层功能实现。每个模块的技术选型与实现方式直接影响系统性能与扩展性,例如传感器选型需平衡精度与…...
