C++ 模板
文章目录
- 一、泛型编程
- 二、 函数模板
- 三、类模板
一、泛型编程
泛型编程:编写与类型无关的通用代码,代码复用的一种方法
在 C++ 中,我们可以通过函数重载实现通用的交换函数 Swap ,但是有一些缺点
- 重载函数只有类型不同,使得代码复用率不好,需要使用新类型时,就必须自己写该类型的重载函数
- 当有一个重载函数出错时,可能需要检查所有的函数
void Swap(int& a, int& b)
{int tmp = a;a = b;b = tmp;
}void Swap(double& a, double& b)
{double tmp = a;a = b;b = tmp;
}
于是 C++ 中引入了模板,可以给函数或类设置模板类型参数,模板类型参数在函数或类中表示广泛的类型,在使用时会替换为正在使用的这个类型
//class 关键字可以换成 typename 关键字,注意:这里不能使用 struct 关键字
template<class T1, class T2,...> //T1、T2,... 是模板类型参数,表示广泛的类型
模板是泛型编程的基础,给函数或类添加模板类型参数,就称为 函数模板 和 类模板
模板是与具体类型无关的通用代码,当我们使用模板并填充某种类型时,编译器就会根据该类型实例化出该模板样式的代码
二、 函数模板
函数模板是与具体类型无关的函数代码,当我们调用模板函数时,编译器会根据实参的类型实例化出该函数模板样式的代码
于是交换函数的通用版本就可以用函数模板简单的实现了
#include <iostream>using namespace std;//T 代表广泛的类型,是调用该模板函数时实参的类型
template<class T> void Swap(T& a, T& b)
{T tmp = a;a = b;b = tmp;
}int main()
{int a1 = 1, b1 = 2;Swap(a1, b1); //向 Swap 模板函数填充 int,编译器自动生成 int 版 Swapcout << a1 << " " << b1 << endl; //输出 2 1double a2 = 1.11, b2 = 2.22;Swap(a2, b2); //向 Swap 模板函数填充 double,编译器自动生成 double 版 Swapcout << a2 << " " << b2 << endl; //输出 2.22 1.11char a3 = 'a', b3 = 'b';Swap(a3, b3); //向 Swap 模板函数填充 char,编译器自动生成 char 版 Swapcout << a3 << " " << b3 << endl; //输出 b areturn 0;
}
在编译阶段,编译器根据实参的类型实例化出该函数模板样式的函数代码

在调用模板函数时:
-
编译器根据实参类型填充模板,然后实例化出实参类型的函数模板样式的代码,这种方式称为 隐式实例化
-
在函数名和参数之间加上 <type>,指定类型 type 填充模板,然后实例化出 type 类型的函数模板样式的代码,这种方式称为 显示实例化
#include <iostream>using namespace std;template<class T> void Swap(T& a, T& b)
{T tmp = a;a = b;b = tmp;
}int main()
{int a = 1, b = 2;Swap<int>(a, b); //指定 int 类型填充模板函数 Swap,编译器自动生成 int 版 Swapcout << a << " " << b << endl; //输出 2 1return 0;
}
其实库中已经实现了通用的交换函数 swap,以后直接使用即可

非模板函数可以和函数模板同名,并且允许函数模板实例化出的函数和非模板函数一样
#include <iostream>using namespace std;int Add(const int& left, const int& right)
{return left + right;
}template<class T>
T Add(const T& left, const T& right)
{return left + right;
}int main()
{//默认调用非模板函数cout << Add(1, 2) << endl; //输出 3//可以实例化出和非模板函数一样的函数//调用函数模板实例化的 int 版cout << Add<int>(1, 2) << endl; //输出 3return 0;
}
调用普通函数时,如果实参和形参数类型不同,可以隐式类型转换,但在以隐式实例化的方式调用模板函数时,如果实参和形参类型不同,不会隐式类型转换
当普通函数和模板函数重名时,并且函数调用传递的实参类型和普通函数的形参类型不匹配时,如果函数模板可以实例化出更匹配参数类型的函数,则会调用函数模板实例化的函数,否则调用普通函数
#include <iostream>using namespace std;int Add(const int& left, const int& right)
{return left + right;
}template<class T1, class T2>
T1 Add(const T1& left, const T2& right)
{return left + (T1)right;
}int main()
{//当函数模板可以实例化出更匹配参数的函数时,调用函数模板实例化的函数Add(1, 2.2);return 0;
}
三、类模板
类模板是与具体类型无关的类代码,用模板类实例化对象时,需要在类名后加上 <type>,指定类型 type 填充模板,然后实例化出 type 类型的类模板样式的代码
于是 Stack 类的通用版本就可以用类模板简单的实现了
#include <iostream>using namespace std;template<class T> class Stack
{
public:Stack(int capacity = 4): _a(new T[capacity]), _top(0), _capacity(capacity){}~Stack();private:T* _a;int _top;int _capacity;
};//当成员函数在类外定义时,需要加上模板类型参数列表
//注意:Stack<T>(T 表示广泛的类型) 才是模板类的类名
template<class T> Stack<T>::~Stack()
{if (_a){delete[] _a;_a = nullptr;_top = _capacity = 0;}
}int main()
{//Stack<int> 为存储整形元素的栈类的类型名Stack<int> s1; //指定 int 类型填充模板类 Stack,编译器自动生成 int 版 Stack//Stack<char> 为存储字符元素的栈类的类型名Stack<char> s2;//指定 char 类型填充模板类 Stack,编译器自动生成 char 版 Stackreturn 0;
}
注意:使用类模板定义对象时,没有东西可以识别为类模板所需要填充的类型,因此类模板只能显示实例化
模板和函数重载的底层原理是一样的,只是重复的事情交给了编译器而已
相关文章:
C++ 模板
文章目录一、泛型编程二、 函数模板三、类模板一、泛型编程 泛型编程:编写与类型无关的通用代码,代码复用的一种方法 在 C 中,我们可以通过函数重载实现通用的交换函数 Swap ,但是有一些缺点 重载函数只有类型不同,…...
JWT安全漏洞以及常见攻击方式
前言 随着web应用的日渐复杂化,某些场景下,仅使用Cookie、Session等常见的身份鉴别方式无法满足业务的需要,JWT也就应运而生,JWT可以有效的解决分布式场景下的身份鉴别问题,并且会规避掉一些安全问题,如CO…...
华为OD机试题 - 最小施肥机能效(JavaScript)
最近更新的博客 华为OD机试题 - 任务总执行时长(JavaScript) 华为OD机试题 - 开放日活动(JavaScript) 华为OD机试 - 最近的点 | 备考思路,刷题要点,答疑 【新解法】 华为OD机试题 - 最小步骤数(JavaScript) 华为OD机试题 - 任务混部(JavaScript) 华为OD机试题 - N 进…...
Python(1)变量的命名规则
目录 1.变量的命名原则 3.内置函数尽量不要做变量 4.删除变量和垃圾回收机制 5.结语 参考资料 1.变量的命名原则 ①由英文字母、_(下划线)、或中文开头 ②变量名称只能由英文字母、数字、下画线或中文字所组成。 ③英文字母大小写不相同 实例: 爱_aiA1 print(…...
Shiro1.9学习笔记
文章目录一、Shiro概述1、Shiro简介1.1 介绍1.2 Shiro特点2、Shiro与SpringSecurity的对比3、Shiro基本功能4、Shiro原理4.1 Shiro 架构(外部)4.2 shiro架构(内部)二、Shiro基本使用1、环境准备2、登录认证2.1 登录认证概念2.2 登录认证基本流程2.3 登录认证实例2.4 身份认证源…...
2.5|iot|嵌入式Linux系统开发与应用|第4章:Linux外壳shell脚本程序编程
1.shell基础 Shell是Linux操作系统内核的外壳,它为用户提供使用操作系统的命令接口。 用户在提示符下输入的每个命令都由shell先解释然后发给Linux内核,所以Linux中的命令通称为shell命令。 通常我们使用shell来使用Linux操作系统。Linux系统的shell是…...
九龙证券|连续七周获加仓,四大行业成“香饽饽”!
本周17个申万职业北上资金持股量环比增加。 北上资金抢筹铝业龙头 本周A股商场全体冲高回落,沪指收跌1.12%,深成指跌2.18%,创业板指跌3.76%。北上资金周内小幅净流入。在大盘体现较差的周四周五,北上资金别离逆市回流67.94亿元、…...
210天从外包踏进华为跳动那一刻,我泪目了
前言 没有绝对的天才,只有持续不断的付出。对于我们每一个平凡人来说,改变命运只能依靠努力幸运,但如果你不够幸运,那就只能拉高努力的占比。 2021年4月,我有幸成为了华为的一名高级测试工程师,正如标题所…...
CMake 引入第三方库
CMake 引入第三方库 在 CMake 中,如何引入第三方库是一个常见的问题。在本文中,我们将介绍 CMake 中引入第三方库的不同方法,以及它们的优缺点。 1. 使用 find_package 命令 在 CMake 中,使用 find_package 命令是最简单和最常…...
软考中级-面向对象
面向对象基础(1)类类分为三种:实体类(世间万物)、接口类(又称边界类,提供用户与系统交互的方式)、控制类(前两类之间的媒介)。对象:由对象名数据&…...
Linux 系统构成:bootloader、kernel、rootfs
写在前面: 本文章旨在总结备份、方便以后查询,由于是个人总结,如有不对,欢迎指正;另外,内容大部分来自网络、书籍、和各类手册,如若侵权请告知,马上删帖致歉。 目录前言bootloaderk…...
SpringCloud - Eureka注册发现
目录 提供者与消费者 Eureka原理分析 搭建Eureka服务 服务注册 服务发现 提供者与消费者 服务提供者: 一次业务中,被其它微服务调用的服务(提供接口给其它微服务)服务消费者: 一次业务中,调用其它微服务的服务(调用其它微服务…...
WampServer安装教程
文章目录简介:官网地址安装步骤:我是阿波,学习PHP记录一下笔记,如果对你有帮助,欢迎一键三连,谢谢! 简介: WampServer是一个用于Windows操作系统的Web开发环境,其名称来…...
Go语言泛型基础
泛型 Go 并不是一种静止的、一成不变的编程语言。新的功能是在经过大量的讨论和实验后慢慢采用的。最初的 Go1.0发布以来,Go语言习惯的模式已经发生了重大变化1.7的context、1.11的modules、1.13 error嵌套等Go的 1.18 版本包括了类型参数的实现,也就是…...
基于android的中医养生app
需求信息: 中医健康养生APP分为四大模块,其中个人中心又分为4大块,游客用户个人中心是空白的。 上图为养生知识推广普及模块的功能结构图。 在养生知识推广普及模块界面,用户可以选择自己感兴趣的模块进行文章浏览,文章…...
2023美赛C代码思路结果【全部更新完毕】注释详尽
C题已完成全部代码,注释详尽,并增加扰动项,保证大家的结果不会撞 需要全部问题的可以点击:https://www.jdmm.cc/file/2708697/ 下面贴出核心代码: -- coding: utf-8 -- TODO: 入口函数 import numpy as np from…...
实现8086虚拟机(二)——模拟CPU和内存
文章目录CPU 架构EU(执行单元)BIU(总线接口单元)小结一下模拟内存模拟 BIU模拟 EU模拟 CPU总结要模拟 8086 CPU 运行,必须知道 CPU 的一些知识。下文的知识点都来自《Intel_8086_Family_Users_Manual 》。CPU 架构 微…...
Windows7下使用VMware11.1.1安装ubuntu-16.04.7
一、说明二、安装说明三、安装步骤详解1、先安装VMware软件2、创建虚拟机3、编辑虚拟机4、开启虚拟机,初始化Linux系统一、说明 虽然VMware和ubuntu最新版已经很高了,我这电脑由于是win7配值还低,所以采用低版本来安装 VMware版本࿱…...
基于SSM框架的CMS内容管理系统的设计与实现
基于SSM框架的CMS内容管理系统的设计与实现 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取项目下载方式🍅 一、项目…...
华为OD机试 - 运动会 | 机试题算法思路 【2023】
最近更新的博客 华为OD机试 - 自动曝光(Python) | 机试题算法思路 【2023】 华为OD机试 - 双十一(Python) | 机试题算法思路 【2023】 华为OD机试 - 删除最少字符(Python) | 机试题算法思路 【2023-02】 华为OD机试 - Excel 单元格数值统计(Python) | 机试题算法思路 …...
UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...
linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...
Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...
NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...
LeetCode - 199. 二叉树的右视图
题目 199. 二叉树的右视图 - 力扣(LeetCode) 思路 右视图是指从树的右侧看,对于每一层,只能看到该层最右边的节点。实现思路是: 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...
uniapp手机号一键登录保姆级教程(包含前端和后端)
目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号(第三种)后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...
uniapp 字符包含的相关方法
在uniapp中,如果你想检查一个字符串是否包含另一个子字符串,你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的,但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...
Python 高效图像帧提取与视频编码:实战指南
Python 高效图像帧提取与视频编码:实战指南 在音视频处理领域,图像帧提取与视频编码是基础但极具挑战性的任务。Python 结合强大的第三方库(如 OpenCV、FFmpeg、PyAV),可以高效处理视频流,实现快速帧提取、压缩编码等关键功能。本文将深入介绍如何优化这些流程,提高处理…...
