【C++精华铺】8.C++模板初阶
目录
1. 泛型编程
2. 函数模板
2.1 函数模板的概念及格式
2.2 函数模板的原理
2.3 模板的实例化
2.4 模板参数的匹配原则
3. 类模板
3.1 类模板格式
3.2 类模板的实例化
1. 泛型编程
什么是泛型编程?泛型编程是避免使用某种具体类型而去使用某种通用类型来进行程序编写的方式,依次来复用某段代码而避免大规模功能相似重复冗余的代码。下面的代码如果想用泛型编程该如何实现。
int add(int a,int b)
{return a + b;
}
double add(double a, int b)
{return a + b;
}
double add(int a, double b)
{return a + b;
}
马云有次说了这么一句话:“世界是懒人创造的,懒不是傻懒,如果你想少干,就要想出懒的方法。 要懒出风格,懒出境界。”C++必然也是有风格有境界的,所以C++中设计了模板实现了泛型编程。
2. 函数模板
2.1 函数模板的概念及格式
模板就是一种模具,通过给这个模具中放不同的材料(类型),来获得不同材料的产品,以此来提高我们的工作效率。而函数模板就是某个函数的模具,与类型无关,在使用的时候参数化,在我们给出特定类型就会生成特定类型的版本。
函数模板的格式:
template<typename T1, typename T2 ...typename Tn>
返回值类型 函数名(形参列表)
{
//函数体
}
根据这个函数的模板我们就可以实现上述add函数的模板:
template<typename L, typename R,typename RET>
RET add(L l, R r)
{return l + r;
}
注:typename是用来定义模板参数的关键字,也可以用class代替。
2.2 函数模板的原理
函数模板本身不是函数,而是一个模具,当我们传入实际类型的时候编译器会根据我们传入的实参类型来推演生成对应类型的函数进行调用。
2.3 模板的实例化
当我们将类型传入模板来生产函数的时候,称之为模板的实例化,模板的实例化分为隐式实例化和显式实例化。
1. 隐式实例化:隐式实例化就是我们不去指定类型,让编译根据我们传入的实参判断其类型传入模板参数列表进行实例化。如下:
template<typename L, typename R>
int add(L l, R r)
{return l + r;
}
int main()
{int a = 0, b = 1;cout << add(a, b) << endl; //根据我传入的a和b自动判断类型进行模板实例化。
}
细心的同学发现,这里我将原来的代码中 typename RET 删掉了,原因就是模板不会对函数的返回值类型进行自动判断,而需要我们手动指定(也就是显式实例化)。
2. 显式实例化:显式实例化就是我们手动向模板传递类型,然后由编译器进行实例化。显式实例化的格式为:
函数名<类型1,类型2,...>(实参列表);
如:
template<typename L, typename R, typename RET>
RET add(L l, R r)
{return l + r;
}
int main()
{int a = 0, b = 1;cout << add<int,int,int>(a, b) << endl;
}
上述代码我们传进去的 a和b的类型与模板参数类型是匹配的,如果不匹配的话编译器会进行隐式类型转化,如果转化失败就报错。如下:
类型转换成功:
template<typename L, typename R, typename RET>
RET add(L l, R r)
{return l + r;
}
int main()
{double a = 0.1;int b = 1;cout << add<int,int,int>(a, b) << endl; //a:double类型隐式转换成int类型
}
输出:
类型转化失败:
template<typename L, typename R, typename RET>
RET add(L l, R r)
{return l + r;
}class Date
{//
};
int main()
{int a = 0, b = 1;cout << add<int,Date,int>(a, b) << endl; //a:类型转化失败
}
输出:
E0304 没有与参数列表匹配的 函数模板 "add" 实例
2.4 模板参数的匹配原则
一个函数的模板函数可以与非模板函数同时存在,并且在没有显式实例化且类型匹配的情况下会优先匹配非模板函数,如果是显式实例化才会调用模板,如下。
template<class T>
void swap(T& a, T& b)
{std::swap(a, b);std::cout << "我是模板 ";std::cout << a << ' ' << b << std::endl;}
void swap(int& a, int& b)
{std::swap(a, b);std::cout << "我是非模板 ";std::cout << a << ' ' << b << std::endl;}
int main()
{int a = 1, b = 2;std::cout << a << ' ' << b << std::endl;swap(a, b); //类型匹配优先调用非模板函数swap<int>(a, b); //调用模板实例化
}
输出:
当我们没有去写模板的时候,函数发生类型不匹配可能会进行隐式类型转换,但是有了模板之后就不会发生隐式类型转化,而是使用模板实例化出来一个更为合适的函数。如下:
没有模板时会发生隐式实例化:
void test(int a, int b)
{std::cout << "我不是模板" << std::endl;
}int main()
{test(2, 2.0);//2.0发生隐式类型转化成int;
}
输出:
存在模板不会发生隐式类型转化,而是使用模板实例化出来一个更为合适的函数:
template<class T1,class T2>
void test(T1 a, T2 b)
{std::cout << "我是模板" << std::endl;
}
void test(int a, int b)
{std::cout << "我不是模板" << std::endl;
}
int main()
{test(2, 2.0);//不发生隐式类型转化而是隐式实例化模板
}
输出:
3. 类模板
3.1 类模板格式
和函数模板一样,类模板是类的一个模具,类模板格式如下:
template<class T1,class T2,class T3,...class Tn>
class 类模板名
{
//类体
};
我们普通类是可以声明和定义分离的,如果类模板要实现声明和定义分离,那么在定义的时候也要加上模板声明。如:
template<class T1, class T2>
class A
{~A(); //声明
};template<class T1,class T2>
A<T1, T2>::~A() //定义
{//...
}
3.2 类模板的实例化
类模板的实例化和函数模板相同,需要在类名后加上尖括号并且指定类型。注:模板名不是类,实例化后才是一个类。
template<class T>
class Date
{//..
};
int main()
{Date<int>;
}
相关文章:

【C++精华铺】8.C++模板初阶
目录 1. 泛型编程 2. 函数模板 2.1 函数模板的概念及格式 2.2 函数模板的原理 2.3 模板的实例化 2.4 模板参数的匹配原则 3. 类模板 3.1 类模板格式 3.2 类模板的实例化 1. 泛型编程 什么是泛型编程?泛型编程是避免使用某种具体类型而去使用某种通用类型来进行…...

离谱的Bug
离谱的 Bug Bug 情况发现 Bug修改 Bug其他感受历史 Bug火星Spirit号Mars Global Surveyor任务 Bug 情况 有一次,我在开发一个网页应用程序时,遇到了一个令人目瞪口呆的Bug。这个Bug出现在一个特定的页面上,当用户点击某个按钮时,…...

leetcode 322. 零钱兑换
本题属于完全背包问题,但要求最少的硬币个数。于是设定dp数组的含义dp[i]:总金额为i时,能凑成i的最少硬币个数。 需要注意初始化dp数组时,除0以外的其他地方需要初始化为INT_MAX以保证在递推过程中能被正确的覆盖。 代码如下: …...

(二)结构型模式:6、外观模式(Facade Pattern)(C++实例)
目录 1、外观模式(Facade Pattern)含义 2、外观模式的UML图学习 3、外观模式的应用场景 4、外观模式的优缺点 5、C实现外观模式的简单实例 1、外观模式(Facade Pattern)含义 外观模式(Facade Pattern)…...

docker的资源控制管理——Cgroups
目录 一、对CPU使用率的控制 1.1 CPU 资源控制 1.2 cgroups有四大功能 1.3 设置cpu使用率上限 查看周期限制和cpu配额限制 进行cpu压力测试然后修改每个周期的使用cpu的时间,查看cpu使用率 1.4 设置cpu资源占用比(设置多个容器时才有效…...

less学习语法
1.CSS函数的补充 1.rgb/rgba/translate/rotate/scale 2.非常好用的css函数: var:使用css定义的变量calc:计算css值,通常用于计算元素的大小或位置blur:毛玻璃(高斯模糊)效果gradient:颜色渐变函数 var:定义变量 css中可以自定…...

在 SHELL 脚本中调用另一个 SHELL 脚本(报错: go: not found)
文章目录 在 SHELL 脚本中调用另一个 SHELL 脚本(报错: go: not found)在 SHELL 脚本中调用另一个 SHELL 脚本一个脚本sudo调另外一个脚本,报错(报错: go: not found) 在 SHELL 脚本中调用另一个…...

07微服务的事务管理机制
一句话导读 在单体应用程序中,事务通常是在单个数据库或单个操作系统中管理的,而在微服务架构中,事务需要跨越多个服务和数据库,这就使得事务管理变得更加复杂和困难。 目录 一句话导读 一、微服务事务管理的定义和意义 二、微…...

CS5523规格书|MIPI转EDP方案设计|替代LT8911芯片电路原理|ASL集睿致远CS替代龙讯
ASL芯片(集睿致远) CS5523是一款MIPI DSI输入,DP/e DP输出转换芯片,可pin to pin替代LT8911龙讯芯片。 MIPI DSI 最多支持 4 个通道,每个通道的最大运行速度为 1.5Gps。对于DP 1.2输出,它支持1.62Gbps和2.…...

【制作npm包5】npm包制作完整教程,我的第一个npm包
制作npm包目录 本文是系列文章, 作者一个橙子pro,本系列文章大纲如下。转载或者商业修改必须注明文章出处 一、申请npm账号、个人包和组织包区别 二、了解 package.json 相关配置 三、 了解 tsconfig.json 相关配置 四、 api-extractor 学习 五、npm包…...

QT:定时器事件
定时器第一种办法: 1.利用事件timerEvent,在帮助文档中找到该字段:[override virtual protected] void QTimer::timerEvent(QTimerEvent *e) 重写该虚函数 //重写定时器事件void timerEvent(QTimerEvent *e);2.启动定时器startTimer(1000); …...

GitHub Actions自动化部署+定时百度链接推送
前言 最近用VuePress搭建了一个静态网站,由于是纯静态的东西,每次修改完文章都要重新打包上传很是麻烦。虽然vuepress-theme-vdoing主题作者提供了GitHub Actions自动化部署的教程文章,但是过于简陋且是19年发布的。。 1. 创建一个GitHub仓…...

PHP学习心得:如何编写可维护的代码
PHP学习心得:如何编写可维护的代码 引言: 在现代的软件开发中,编写可维护的代码是非常重要的。无论是个人项目还是团队项目,可维护的代码可以提高开发效率,减少维护成本,确保代码的质量和可扩展性。本文将…...

使用vscode进行远程调试
官方调试手册:vscode官方调试手册 1.安装python扩展 如果是远程连接的话,一定要在ssh上启用扩展。不然创建基于python的配置文件时就会提示,无python扩展。 2.新建配置文件,并修改参数 点击左侧第四个按钮,运行与调试…...

LinuxC编程——进程
目录 一、概念1.1 程序1.2 进程 二、特点⭐⭐⭐三、进程段四、进程分类五、进程状态六、进程状态转换图七、函数接口1. 创建子进程2. 回收进程资源3. 退出进程4. 获取进程号 八、守护进程 一、概念 进程和程序是密不可分的两组概念,相对比,便于理解。 1.…...

深入理解设计模式-结构型之适配器
适配器模式(Adapter Pattern): 适配器模式用于将一个类的接口转换成另一个类的接口,以使两者能够一起工作。适配器模式通常用于处理已经存在的类,让它们能够与其他类协同工作,而不需要修改原始类的代码。&…...

桥梁结构健康监测系统,智能预警降低桥梁安全隐患
桥梁通常位于现代综合交通网络中的咽喉部位,对区域经济发展起着重要的推进作用,然而在为社会经济发展做出巨大贡献的同时,它们不可避免地会在荷载作用、环境侵蚀和自然灾害等影响下出现材料腐蚀劣化、结构损伤开裂、性能退化和功能失效等损伤…...

夏威夷等全球多地深陷「末日狂烧」,关键时刻 AI 监测能否跑赢野火?
内容一览:当地时间 8 月 8 日,美国夏威夷州突发野火,当地居民和游客不得不跳入太平洋中躲避火势。截至 8 月 17 日,这场野火已经造成110 人死亡,超过 1000人失踪。与此同时,美国、加拿大、法国等地也正遭遇…...

解决多模块内核心模块有接口打包成jar后被依赖并调用遇到的问题(springcloud集成ruoyi.quartz)
项目准备开发个新功能,刚好很喜欢ruoyi写的任务调度,因此想到了集成ruoyi.quartz模块 ,遇到了很多问题: 首先因为ruoyi.quartz模块依赖了ruoyi.common模块,因此第一步我需要把common模块一部分依赖项复制到了quartz模块内…...

【kubernetes系列】Kubernetes之Kubelet运行机制和状态更新机制
Kubelet运行机制 Kubelet是Kubernetes中的一个重要组件,在每个 Node 节点上都会启动 kubelet 服务。 该服务主要用于处理 Master 节点下发到本节点的任务,管理 Pod及Pod 中的容器。每个kubelet 进程会在 API Server 上注册节点自身信息,定期…...

(学习笔记-进程管理)怎么避免死锁?
死锁的概念 在多线程编程中,我们为了防止多线程竞争共享资源而导致数据错乱,都会在操作共享资源之前加上互斥锁,只有成功获得到锁的线程,才能操作共享资源,获取不到锁的线程就只能等待,直到锁被释放。 那…...

【golang】链表(List)
List实现了一个双向链表,而Element则代表了链表中元素的结构。 可以把自己生成的Element类型值传给链表吗? 首先来看List的四种方法。 MoveBefore方法和MoveAfter方法,它们分别用于把给定的元素移动到另一个元素的前面和后面。 MoveToFro…...

android平台的语音聊天助手源码
目录 1 android平台的语音聊天助手源码 1.1 //js处理工具类 1.1.1 openImage 1.2 LoadWebDetails android平台的语音聊天助手源码package com.shrimp.xiaoweirobot.net; import java.util.ArrayList;...

Python读取Word统计词频输出到Excel
1.安装依赖的包 "# 读取docx\n", "!pip install python-docx\n", "!pip install -i https://pypi.tuna.tsinghua.edu.cn/simple python-docx\n", "# 中英文分词\n", "!pip install jieba\n", "!pi…...

windows docker mysql8.0 挂载配置文件不生效的问题
原因 mysql 8.0 遇到sql_modeonly_full_group_by的问题,于是就自定义my.cnf 去掉only_full_group_by,修改my.cnf 文件后,进行映射启动 docker run 命令 docker run -p 3306:3306 --privilegedtrue --restartalways -d --name axsc-mysql -…...

openGauss学习笔记-42 openGauss 高级数据管理-触发器
文章目录 openGauss学习笔记-42 openGauss 高级数据管理-触发器42.1 语法格式42.2 参数说明42.3 示例 openGauss学习笔记-42 openGauss 高级数据管理-触发器 触发器会在指定的数据库事件发生时自动执行函数。 42.1 语法格式 创建触发器 CREATE TRIGGER trigger_name { BEFORE…...

Leetcode33 搜索旋转排序数组
题解: /*** 旋转排序数组可分为N1 N2两个部分,如:[4,5,6,7,1,2,3],N1为[4,5,6,7],N2为[1,2,3]** 必然满足以下两个条件:* 1. N1和N2都是分别递增的;* 2. N1中的所有元素大于N2中的所有元素;** …...

docker 第一章
目录 1.安装 docker 2.镜像、容器 3.总结 1.安装 docker 2.镜像、容器 3.总结 容器在 linux 上的本机运行,与其他容器共享主机的内核。它运行的是一个独立的进程,不占用其他任何可执行文件的内存,非常轻量级。...

注册中心 —— SpringCloud Netflix Eureka
Eureka 简介 Eureka 是一个基于 REST 的服务发现组件,SpringCloud 将它集成在其子项目 spring-cloud-netflix 中,以实现 SpringCloud 的服务注册与发现,同时提供了负载均衡、故障转移等能力,目前 Eureka2.0 已经不再维护…...

2023年国赛数学建模思路 - 案例:异常检测
文章目录 赛题思路一、简介 -- 关于异常检测异常检测监督学习 二、异常检测算法2. 箱线图分析3. 基于距离/密度4. 基于划分思想 建模资料 赛题思路 (赛题出来以后第一时间在CSDN分享) https://blog.csdn.net/dc_sinor?typeblog 一、简介 – 关于异常…...