行业知识
C++——模板初阶与泛型编程
文章目录
- 专栏导读
- 文章导读
- 引例
- 函数模板
- 函数模板的概念
- 函数模板的格式
- 函数模板的原理
- 函数模板的实例化
- 隐式实例化
- 显式实例化
- 一个疑问
- 模板参数的匹配原则
- 类模板
- 类模板的定义格式
- 类模板的实例化
专栏导读
作者简介:花想云,在读本科生一枚,致力于 C/C++、Linux 学习。
本文收录于 C++系列,本专栏主要内容为 C++ 初阶、C++ 进阶、STL 详解等,专为大学生打造全套 C++ 学习教程,持续更新!
相关专栏推荐:C语言初阶系列 、C语言进阶系列 、数据结构与算法
文章导读
本章我们将学习模板,与泛型编程初次见面。C++相比于C语言有这么多丰富的接口与类型,都源于泛型编程。本章的内容为模板初阶知识,为接下来的STL学习打下坚实的基础。
引例
如何实现一个通用的交换函数(swap)呢?我们已经学过函数重载的使用,函数重载在这种场景下貌似作用很大。
void Swap(int& a, int& b){auto tmp = a;a = b;b = tmp;}void Swap(double& a, double& b){auto tmp = a;a = b;b = tmp;}void Swap(char& a, char& b){auto tmp = a;a = b;b = tmp;}//...虽然函数重载可以实现,但是有点吃力。最糟心的事儿是明明这些函数几乎都长一个样子,仅仅是参数类型不同而已,但是每多一个类型就得写一个对应的重载函数。
那么有什么办法能做到一劳永逸呢?能否做到告诉编译器:我给你一个模板,你来帮我实现每个函数,只是换一下参数类型就OK了?
这就是我们今天要讲到的模板——模板是泛型编程的基础。模板不仅适用于函数,也适用于类。
函数模板
函数模板的概念
函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生函数的特定类型版本。
函数模板的格式
template返回值类型 函数名(参数列表){//...函数体}示例1
templatevoid Swap(T& a,T& b){auto tmp = a;a = b;b = tmp;}注意事项
- typename后面的内容不一定是T,可自由指定;
- typename是用来定义模板参数关键字,也可以使用class(切记:不能使用struct代替class);
示例2
templatevoid Swap(N& a, N& b){auto tmp = a;a = b;b = tmp;}函数模板的原理
函数模板是一个描述的过程、一幅设计图、一个模板,并不是真正的函数。编译器会根据模板使用特定方式产生具体类型函数。所以其实模板就是将本来应该我们做的重复的事情交给了编译器去做(想想印刷术的原理)。
- 在编译器编译阶段,编译器需要根据传入的实参类型来推演生成对应类型的函数以供调用。
比如:当用double类型使用函数模板时,编译器通过对实参类型的推演,将T确定为double类型,然后产生一份专门处理double类型的代码,对于字符类型也是如此。
函数模板的实例化
用不同类型的参数使用函数模板时,称为函数模板的实例化。模板参数实例化分为:隐式实例化和显式实例化。
隐式实例化
让编译器根据实参推演模板参数的实际类型。
示例1
templateT Add(T a, T b){return a + b;}void Test(){int a = 10;int b = 100;cout return a + b;}void Test(){int a = 10;double d = 3.14;cout return a + b;}void Test(){int a = 10;double d = 3.14;cout return a + b;}void Test(){int a = 10;double d = 3.14;cout auto tmp = a;a = b;b = tmp;}void Test(){int a = 10;int b = 100;Swap(a,b);char c1 = 'a';char c2 = 'b';Swap(c1, c2);}return a + b;}int Add(int a, int b){return a + b;}void Test(){int a = 10;int b = 100;cout cout cout int a = 10;int b = 100;double d = 3.14;cout // 类内成员定义};public://...private:T* _a;size_t _size;size_t _capacity;};
下一篇:路由器怎么重启服务器密码?