首页 > 模板1.0 -- 模板基本原理

模板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 Arr
{public:Str():_a(a){}private:T _a;
}Arr<int> arr;

上面的调用就是一个显式的实例化的过程

更多相关:

  • 草色新雨中, 松声晚窗里。之前我们学习 Power Query 都是用鼠标就完成了很多复杂的操作。虽然 PowerQuery 已经将大部分常用功能内置成到功能区。基本能完成我们大部分的报表自动化功能。但是总有些复杂的或者个性化的问题是开发团队没有预先想到的,这时我们就需要学习 M 语言。一、M 语言在哪里?M语言的函数公式有三个地...

  • 前言从2020年3月份开始,计划写一系列文档--《小白从零开始学编程》,记录自己从0开始学习的一些东西。第一个系列:python,计划从安装、环境搭建、基本语法、到利用Django和Flask两个当前最热的web框架完成一个小的项目第二个系列:可能会选择Go语言,也可能会选择Vue.js。具体情况待定,拭目以待吧。。。基本概念表达式表...

  • 1.1函数1.1.1什么是函数函数就是程序实现模块化的基本单元,一般实现某一功能的集合。函数名:就相当于是程序代码集合的名称参数:就是函数运算时需要参与运算的值被称作为参数函数体:程序的某个功能,进行一系列的逻辑运算return 返回值:函数的返回值能表示函数的运行结果或运行状态。1.1.2函数的作用函数是组织好的,可重复使用的,用来...

  • 原标题:基于Python建立深度神经网络!你学会了嘛?图1 神经网络构造的例子(符号说明:上标[l]表示与第l层;上标(i)表示第i个例子;下标i表示矢量第i项)单层神经网络图2 单层神经网络示例神经元模型是先计算一个线性函数(z=Wx+b),接着再计算一个激活函数。一般来说,神经元模型的输出值是a=g(Wx+b),其中g是激活函数(...

  • 在学习MySQL的时候你会发现,它有非常多的函数,在学习的时候没有侧重。小编刚开始学习的时候也会有这个感觉。不过,经过一段时间的学习之后,小编发现尽管函数有很多,但是常用的却只有那几个。今天小编就把常用的函数汇总一下,为大家能够能好的学习MySQL中的函数。MySQL常使用的函数大概有四类。时间函数、数学函数、字符函数、控制函数。让我...

  • 原文出处: 韩昊    1 2 3 4 5 6 7 8 9 10 作 者:韩 昊 知 乎:Heinrich 微 博:@花生油工人 知乎专栏:与时间无关的故事   谨以此文献给大连海事大学的吴楠老师,柳晓鸣老师,王新年老师以及张晶泊老师。   转载的同学请保留上面这句话,谢谢。如果还能保留文章来源就更感激不尽了。 我保证这篇文章...

  • 原文出处: 韩昊   我保证这篇文章和你以前看过的所有文章都不同,这是 2012 年还在果壳的时候写的,但是当时没有来得及写完就出国了……于是拖了两年,嗯,我是拖延症患者…… 这篇文章的核心思想就是: 要让读者在不看任何数学公式的情况下理解傅里叶分析。 傅里叶分析不仅仅是一个数学工具,更是一种可以彻底颠覆一个人以前世界观的思维...

  • 很多Linux高手都喜欢使用screen命令,screen命令可以使你轻松地使用一个终端控制其他终端。尽管screen本身是一个非常有用的工具,byobu作为screen的增强版本,比screen更加好用而且美观,并且提供有用的信息和快捷的热键。 想象一下这样一个场景:你通过Secure Shell(ssh)链接到一个服务器,并...

  • NarrowbandPrimary Synchronization Signal时域位置每1个SFN存在一个NPSSSFNSubframeSymbol长度每个SFN5最后11个symbol11个symbols频域位置NB-IOT下行带宽固定180kHz,一个PRB,12个子载波。...

  •  [h1]反斜杠只能够阻止一个字符  [h2]位于键盘的左上角,和~公用一个键。...

  • 英语的重要性,毋庸置疑!尤其对广大职场人士,掌握英语意味着就多了一项竞争的技能。那,对于我们成人来说,时间是最宝贵的。如何短时间内在英语方面有所突破,这是我们最关心的事情。英语学习,到底有没有捷径可以走,是否可以速成?周老师在这里明确告诉大家,英语学习,没有绝对的捷径走,但是可以少走弯路。十多年的教学经验告诉我们,成功的学习方法可以借...

  • 展开全部 其实IDLE提供了一个显32313133353236313431303231363533e78988e69d8331333365663438示所有行和所有字符的功能。 我们打开IDLE shell或者IDLE编辑器,可以看到左下角有个Ln和Col,事实上,Ln是当前光标所在行,Col是当前光标所在列。 我们如果想得到文件代码...

  • 前言[1]从 Main 方法说起[2]走进 Tomcat 内部[3]总结[4]《Java 2019 超神之路》《Dubbo 实现原理与源码解析 —— 精品合集》《Spring 实现原理与源码解析 —— 精品合集》《MyBatis 实现原理与源码解析 —— 精品合集》《Spring MVC 实现原理与源码解析 —— 精品合集》《Spri...

  • 【本文摘要】【注】本文所述内容为学习Yjango《学习观》相关视频之后的总结,观点归Yjango所有,本文仅作为学习之用。阅读本节,会让你对英语这类运动类知识的学习豁然开朗,你会知道英语学习方面,我们的症结所在。学习英语这类运动类知识,需要把握四个原则第一,不要用主动意识。第二,关注于端对端第三,输入输出符合实际情况第四,通过多个例子...

  • 点云PCL免费知识星球,点云论文速读。文章:RGB-D SLAM with Structural Regularities作者:Yanyan Li , Raza Yunus , Nikolas Brasch , Nassir Navab and Federico Tombari编译:点云PCL代码:https://github.co...