模板1.0 -- 模板基本原理
为什么需要模板
我们经常有这样的一种使用的情形,就是我们可能需要设计一个函数,然后函数的参数可能是整形的,也可能是浮点型的,还有可能是其他的类型的,这个时候如果对于每一个类型都写一个函数,未免有点太复杂了
我们有以下几个方法来实现一个函数针对不同的类型都能够实现
法一:通过函数重载实现
比如我们想要写一个相加的函数,我们需要实现函数的重载
int Add(const int a,const int b)
{return a+b;
}
double Add(cosnt double a,const double b)
{return a+b;
}
char Add(const char a,const char )
缺点分析:
1. 一个类出现时就需要继续重载一个函数
2. 代码的复用率低
3. 如果一个函数只是返回值不同,函数的重载还解决不了问题
4. 如果函数的逻辑错误了,那么所有的函数都需要修改,麻烦
法二:使用公共的基类
我们可以将重复的代码放在一个公共的基类,然后进行一个继承
缺点:
1. 公共的代码放在了基类里面就缺少了类型检查的优点了
2. 一个简单的函数,以后使用了继承之后,以后维护起来麻烦
法三:使用宏函数
#define Add(a,b) ((a)+(b))
缺点:
1. 没有了类型检查
2. 在预处理阶段就被替换掉了,不方便调试
引入模板
C++为了解决上面的问题,于是就引入了模板的使用,像下面的形式来实现Add函数的复用
template<class T>
T Add(const T& a,const T&b)
{return a+b;
}
其中我们使用class的时候,也是可以使用typename这个关键字的
我们在其他的地方调用这个模板函数的时候,就可以使用下面的方式进行一个调用的过程
int x = 1;
int y = 2;
double m = 1.0;
double n = 2.0;Add(x,y);
Add(m,n);
上面的两次对模板函数的调用是不是调用的同一个函数呢,答案:不是。他们调用了不同的函数,这里引入的一个概念就是模板的实例化
我们经常听到的一个概念是对象的实例化,就是我们拿一个类去实例化一个对象,比如我们使用下面的代码去实例化一个string的对象
string str;
同样的我们的模板也是有实例化的一个过程的,就是在我们调用我们函数的时候,根据我们的参数进行一个推演,比如刚刚的那个Add(x,y);这个 时候编译器会根据参数的类型,实例化生成一个参数是整形的Add函数,然后在对他进行一个调用,这个就是简单的实例化的过程。
所以说上面的两次调用实际上是生成了不同的函数,然后进行的一个调用的过程
小问题
问题一:模板函数和实例函数共存
还是上面Add函数,如果我们这个时候在上面的模板函数的基础之上又实现了一个函数,这个时候会如何调用呢
int Add(const int& a,const int& b)
{return a+b;
}
在这种情况下,如果我们有已经实例化的函数,这个时候会直接调用我们已经实例化的函数,如果没有已经 实例化的函数,这个时候才会去找我们的模板函数,然后实例化一个函数进行一个调用的过程
问题二:模板函数和实例函数参数不匹配
还是上面的程序,我们即有了一个模板函数,又有了一个实例函数,这个时候我们在使用的时候,传递的参数不是两个整形而是两个双精度浮点型,那么这个时候是如何调用的呢
double a = 1.0;
double b = 2.0;
Add(a,b);
这个时候会检查我们的实例函数,但是参数的类型不匹配,所以实际上是生成了一个参数是double类型的模板函数,然后再进行函数的一个调用的过程
如果我们的参数一个是int,一个是double的,这个时候又是怎么样的呢,由大家自己去验证吧
这里我们还需要注意的一个问题就是,实例化函数中的第二个参数不是一个const的时候,这个时候,我们的給 我们的参数传入的是一个double的变量的时候,会发生隐式类型的转换的,这个时候会生成一个临时的变量,这个临时的变量具有常性,所以我们应该在参数上面加上一个const
问题三:模板实例化和类型检查
我们知道我们的模板函数只有在实例化的时候,才会生成可执行代码的,如果我们在VS下面测试的时候,编译器是不会对模板函数的内部进行检查的,比如我们少写了一个分号,但是在linux下面使用g++进行 编译的时候是会进行一个检查的过程的
模板类
模板类也很容易实现,只不过在使用的时候,我们需要对模板类进行一个显式的实例化的过程
template<class T>
class Arr
{public:Str():_a(a){}private:T _a;
}Arr<int> arr;
上面的调用就是一个显式的实例化的过程
相关文章:
[置顶] 我的GB28181标准开发里程碑——基于eXosip的IPC端与SPVMN注册成功
昨天编译搭建好eXosip的开发环境后,今天完成了SIP注册功能,里程碑一战啊!加油加油,成功就在眼前! 今天基于eXosip做了一个IPC客户端,成功与公安部的SPVMN视频监控联网调测软件自测工具进行注册交互…

mysql如何避免特殊字符查询_如何避免MySQL中的特殊字符?
慕的地10843我已经用Java开发了自己的MySQL转义方法(如果对任何人都有用的话)。请参阅下面的类代码。警告:如果启用了任何_反斜杠_转义SQL模式,则出错。private static final HashMap sqlTokens;private static Pattern sqlTokenPattern;static{ …

visio 2010 修改 默认字体 字号大小 方法
哈哈,我这是标题党,先给大家泼个冷水。Visio2010 并不支持对一次性地修改绘图中所有图形的字体大小!但可以有一个比较笨的方法解决。1.新建一个模具2.将常用的图形放到这个模具中3.对每个图形进行编辑4.对这个形状的字体,字号进行…

[BZOJ3329] Xorequ
题解: 网上的方法基本是建立在发现临位不能相等的基础上的 这个很好证。。 但是不利用这个特征也是可以的 x^2x3x 我们考虑二进制的前i位,我们会发现3x最多涉及到了前i2位 于是我们可以记录一下前i位的3x的i1,i2位的状态,以及第i位填了什么 因…

Asp.net中时间格式化的几种方法
1. 数据控件绑定时格式化日期方法:<asp:BoundColumn DataField"AddTime" HeaderText"添加时间" DataFormatString"{0:yyyy-MM-dd HH:mm}></asp:BoundColumn><asp:BoundField DataField"AddTime" HeaderText"添加时间&q…

centos设置网络自动启动
问题描述 centos7虚拟机如何设置开机自启动网络设置 解决方法 切换到root用户进入到网络设置的目录下面cd /etc/sysconfig/network-scripts/当前目录下面有一个类似于ifcfg-ens33,使用vim打开文件进行编辑,将ONBOOTno修改成为yes就可以了

mysql删除原则_MySQL数据库的增删选查
数据库是专门存储数据对象的容器,这里的数据对象包括表、视图、触发器、存储过程等,其中表是最基本的数据对象。创建数据库在 MySQL 数据库中存储数据对象之前,先要创建好数据库。语法:create database [if not exists] [[default…

ubuntu网卡配置
1、dhcp自动获取 sudo vi /etc/network/interfaces auto eth0 iface eth0 inet dhcp 设置生效: sudo /etc/init.d/networking restart 或 sudo dhclient eth0 2、静态IP地址 sudo vi /etc/network/interfaces auto eth0 iface eth0 inet static address 192.168.3.90 netmask 2…

自动化运维工具----ansible
自动化运维工具----ansible ansible是新出现的运维工具是基于Python研发的糅合了众多老牌运维工具的优点实现了批量操作系统配置、批量程序的部署、批量运行命令等功能。 主要模块以及功能: 1 command 2 user 3 group 4 cron 5 copy 6 file 7 ping 8 yum 9 service …

【内核】嵌入式linux内核的五个子系统
Perface Linux内核主要由进程调度(SCHED)、内存管理(MM)、虚拟文件系统(VFS)、网络接口(NET)和进程间通信(IPC)5个子系统组成,如图1所示。 图1 Li…

git用户文档1 — git基础
1. git基础 1.1 分布式 我们把远端仓库(云端的仓库)称为repo,repo必须有一个master分支,就是主分支。 repo除了有一个master分支,还有很多其他的分支,若干个分支之间存储的数据一版都是不一样的本地可以git clone下来repo的mast…

MySQL5.7的date类型_Mysql5.7 虚拟列数据类型为DATE时,如何存入数据?
表结构:v_date为虚拟列CREATE TABLE test ( json TEXT NULL, date DATETIME NULL DEFAULT NULL, v_date DATE AS (json_extract(json,$.date)) VIRTUAL)COMMENT测试表\r\nCOLLATEutf8mb4_general_ciENGINEInnoDB;插入:INSERT INTO test (json) …

找出字符串中所有数字
刚才网友在SKYPE问Insus.NET一个问题,在MS SQL中,怎样找出一个字符串所有数字。 Insus.NET使用较简单与平常的方法,就是使用循环的方法,循环字符串中每一个字符,并插入至一个表变量中。然后再SELECT这个表变量…

Safair 浏览器cllick事件不生效或者需要双击才生效
针对Safair 浏览器cllick事件不生效或者需要双击才生效的解决方案。 方法一:给元素加上cursor: pointer样式。(不生效) 方法二:ios事件机制不一样,将click事件改为mousedown或其他事件即可解决。(需要双击&…

springboot mysql行锁_SpringBoot基于数据库实现简单的分布式锁
本文介绍SpringBoot基于数据库实现简单的分布式锁。1.简介分布式锁的方式有很多种,通常方案有:基于mysql数据库基于redis基于ZooKeeper网上的实现方式有很多,本文主要介绍的是如果使用mysql实现简单的分布式锁,加锁流程如下图&…

简单shell
执行脚本结果重定向 sh hah.sh hello 1>>/home/qiso/job.log 2>&1 上面这句话的意思是 首先通过sh执行脚本hah.sh,其中执行这个脚本的时候,需要传入参数,参数是hello, 1表示的是标准输出,以上脚本执行…

个人随笔、收藏——(包括技术、设计思想等)
1、开源自动化工具 Sahi、Selenium、AutoIt Sahi,是一个用于Web应用程序的自动测试工具。Sahi运行为一个代理服务器,必须把浏览器的代理设置为Sahi服务器。 然后Sahi注入javascript来访问Web页面中的元素。Sahi支持Http与Https并且独立于Web站点或Web应用…

安装QCreator2.5+Qt4.8.2+MinGW_gcc_4.4
QCreator最近升级了。正好想试试新功能,所以把原来安装的QCreator2.3.1Qt4.7.1卸载了。安装新的版本。具体步骤如下: 1# 下载QCreator2.5version。 2# 下载Qt4.8.2version。 3# 根据Qt官网给的链接,下载MinGW-gcc440_1(因为从QCre…

第一次结对作业
211606368林书浩 211606352陈彬 一、预估与实际 PSP2.1Personal Software Process Stages预估耗时(分钟)实际耗时(分钟)Planning计划• Estimate• 估计这个任务需要多少时间3540Development开发• Analysis• 需求分析 (包括学习…

mysql如何根据业务分表设计_mysql分表分库的应用场景和设计方式
很多朋友在论坛和留言区域问mysql在什么情况下才需要进行分库分表,以及采用何种设计方式才是最优的选择,根据这些问题,小编为大家整理了关于MySQL分库分表的应用场景和最优的设计方式举例。一. 分表场景:对于大型的互联网应用来说…

简单protobuf
protobuf的数据类型,有最简单的那种数据类型,就是一个文件中,定义了一个message 可以在一个文件中定义两个message,两个message之间是没有关联的可以在一个文件中,定义两个message,其中一个是简单的&#x…

迭代器、生成器
迭代器 lst range(10) #生成一个枚举列表 从0-9 itr iter(lst) #生成一个迭代器 itr.next() #访问迭代器方法 遍历迭代器 try:while True:val itr.next()print val except StopIteration:pass 注意: 1、如果对list dict tuple 用for遍历,则for内部自动…

Linq 无法删除尚未附加的实体的问题
Linq删除个集合数据, 刚开始用的注释掉的那行, 会提示"无法删除尚未附加的实体"错误, 使用Attach方法依然不行. 想想以前用过DeleteAllOnSubmit没啥问题哈, 估计是_db对象的引用问题, 换了种写法就OK了. //删掉所有工作组部门关联 //wgdrLst Wor…

从云端到边缘 AI推动FPGA应用拓展
近日,全球最大的FPGA厂商赛灵思宣布收购深鉴科技的消息,引发人工智能芯片行业热议,这也是首起中国AI芯片公司被收购的案例。值得注意的是,收购深鉴科技的赛灵思在2018年下半年重点发展方面是汽车自动驾驶。 FPGA市场的竞争正在发生…

mysql中的%_mysql入门
MySQL数据库1 数据库概念(了解)1.1 什么是数据库数据库就是用来存储和管理数据的仓库!数据库存储数据的优先:可存储大量数据;方便检索;保持数据的一致性、完整性;安全,可共享;通过组合分析&am…

关于timewait状态
四次挥手 主动关闭连接的一方,调用close,协议层发送FIN包,在TCP报头的FIN字段设置为1,意思是我要和你断开链接,主动关闭连接的一方进入到了FIN_WATI_1状态 被动关闭的一方收到了FIN包之后,协议层回复ACK包…

DWZ基于ajax重复请求的修复
在同一个通用上传插件,每次都需要客户端去请求服务器,返回的html页面,如果请求的间隔很短的话,ajax会认为是重复作废的请求,这个时候需要修改一下源码来达到在短时间内重复请求也能得到响应找到js/dwz.ajax.js修改源码为function ajaxTodo(url, callback){t Date.parse(new D…

TLS/HTTPS 证书生成与验证
https://www.cnblogs.com/kyrios/p/tls-and-certificates.html 最近在研究基于ssl的传输加密,涉及到了key和证书相关的话题,走了不少弯路,现在总结一下做个备忘 科普:TLS、SSL、HTTPS以及证书 不少人可能听过其中的超过3个名词&am…

高并发系统搭建:web负载均衡
高并发系统搭建:web负载均衡 所谓的负载均衡就是让多个请求尽量均衡的分配到不同的机器上面去 1. HTTP负载均衡 当用户的请求发来之后,web服务器通过修改HTTP响应报头中的Location标记,返回一个新的url,然后浏览器继续请求这个…

centos 7.0 安装mysql_CentOS 7.0yum安装MySQL
1.下载mysql的repo源$ wget http://repo.mysql.com/mysql-community-release-el7-5.noarch.rpm2.安装mysql-community-release-el7-5.noarch.rpm包$ sudo rpm -ivh mysql-community-release-el7-5.noarch.rpm安装这个包后,会获得两个mysql的yum repo源:/…