C++初识模板

在这里插入图片描述

文章目录

  • 👑1. 泛型编程
  • 👒2. 模板
    • 📿2.1 函数模板
      • 🎶2.11 类型推理
      • 🎶2.12 函数模板实例化
      • 🎶2.13 匹配原则
    • 📿2.2 类模板

👑1. 泛型编程

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;
}
void Swap(char& a, char& b)
{char tmp = a;a = b;b = tmp;
}

上面这段代码,是一个交换函数的重载,这虽然可以处理不同的类型,但是每个类型都要我们写对应的重载函数,而且复用率不是很高。

祖师爷可能也感觉这样不好用,设计了模板这个概念,就类似于印刷术,有一个模子在这里,想怎么印刷就怎么印刷。

image-20230709214359217

泛型编程是一种编程范式,编写与特定类型无关的算法和数据结构,使其可以适用于多种数据类型,而无需为每种类型编写特定的代码。

在C++中,主要就通过模板来实现。

👒2. 模板

📿2.1 函数模板

函数模板是一种用于生成通用函数的模板。它允许在函数定义中使用类型参数,以便函数可以适用于多种数据类型。函数模板的语法如下:

template<typename T>
void func(T x)
{//...////...
}

这里的template也可以用class来代替

typename是定义函数模板的关键字

🎶2.11 类型推理

函数模板类似一张图纸,它本身并不是函数,是编译器会根据函数调用时候传递的参数类型进行推导,找到最匹配的模板参数类型。

template<typename T>
T Max(T a, T b)
{return a > b ? a : b;
}
int main()
{cout << Max(1, 3) << endl;cout << Max(2.2, 1.3) << endl;cout << Max('a', 'b') << endl;return 0;
}

这段代码就会根据参数的不同类型,推导适合这些参数的模板参数。

image-20230709222839397

🎶2.12 函数模板实例化

这些都是调用的同一个函数吗?

在推导完毕之后,会生成对应的函数实例,这叫做函数模板的实例化。它将根据模板描述中的模板参数类型,将函数模板中的代码替换为具体类型,并生成一个实际的函数定义。

image-20230709223852238

所以可以看出这些调动都是各种推导出的实际函数,并不是同一个函数。

自动推导,我们也叫隐式实例化

但如果我们模板只设置了一个类型参数,但我们传了2个类型不同的值,这时候就无法进行自动推导:

image-20230709224737148

这时候就可以用显式实例化

template<typename T>
T Max(T a, T b)
{return a > b ? a : b;
}
int main()
{//在函数名后的<>中指定模板参数的实际类型Max<int>(1.1, 3);Max<char>('a', 99);return 0;
}

🎶2.13 匹配原则

当编译器进行模板参数匹配时,它会优先考虑完全匹配的情况。如果有一个非模板函数,而且该函数模板还能被实例化成这个非模板函数的话,这时候编译器就不需要特化模板。

template<class T1, class T2>
T1 Add(T1 a, T2 b)
{std::cout << "T Add()" << std::endl;return a + b;
}
int Add(int a, int b)
{std::cout << "int Add()" << std::endl;return a + b;
}
int main()
{Add(1, 2);	//非模板函数完全匹配,不需特化Add<int>(1, 2);	//指定调用模板函数Add(1, 1.2);	//模板函数可以生成更加匹配的版本return 0;
}

Tips:

普通函数可以进行自动类型转换,模板函数不允许自动类型转换

📿2.2 类模板

类模板是一种用于生成通用类的模板。它允许在类定义中使用类型参数,以便可以创建适用于多种数据类型的类实例。类模板的语法如下:

template<typename T>
class ClassName
{// 类成员和方法
};

在数据结构中,可能会存储不同类型的数据,有了类模板,就十分方便了:

template<class T>
class Stack
{
public:Stack(){//...}//...void push_back(const T& val){//...}//...
private:T _arr;int _size;int _capacity;
};
int main()
{Stack<int> st_i;	//整型st_i.push_back(1);st_i.push_back(2);Stack<double> st_d;	//浮点型st_d.push_back(1.1);st_d.push_back(1.2);
}

Tips:

类模板实例化与函数模板实例化不同,类模板实例化需要在类模板后面跟上<T>,而且和普通类不一样的实例化也不一样

template<class T>
class A
{};class B
{};int main()
{A<int> a;	//A是类名	A<int>是类型B b;	//B既是类名也是类型return 0;
}

本期分享就到这里咯,如果有帮助的话点赞支持支持,我们下期再见,如果还有下期的话。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/15551.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL基础(五)视图、存储过程和存储函数、变量

目录 常见的数据库对象 ​编辑 视图 创建视图 改变视图 优缺点 存储过程与存储函数 创建存储过程 创建存储函数 存储过程和存储函数的区别 存储过程和函数的查看、修改、删除 查看 修改 删除 存储过程的优缺点 优点 缺点 变量 系统变量 查看系统变量 修改…

Redis的一个大Key

什么是 redis 的大 key? redis 的大 key 不是指存储在 redis 中的某个 key 的大小超过一定的阈值&#xff0c;而是该 key 所对应的 value 过大对于 string 类型来说&#xff0c;一般情况下超过 10KB 则认为是大 key&#xff1b;对于set、zset、hash 等类型来说&#xff0c;一…

Linux —— Gitee

目录 一&#xff0c;介绍 二&#xff0c;使用 一&#xff0c;介绍 用于代码托管、版本控制、多人协助等&#xff1b; Gitee是开源中国&#xff08;OSChina&#xff09;推出的基于Git的代码托管服务&#xff1b;深圳市奥思网络科技有限公司&#xff1b; 二&#xff0c;使用 网…

3.9.错误处理的理解以及错误的传播特性

目录 前言1. thrust2. error总结 前言 杜老师推出的 tensorRT从零起步高性能部署 课程&#xff0c;之前有看过一遍&#xff0c;但是没有做笔记&#xff0c;很多东西也忘了。这次重新撸一遍&#xff0c;顺便记记笔记。 本次课程学习精简 CUDA 教程-错误处理的理解以及错误的传播…

【爬虫】5.4 Selenium 实现用户登录

目录 任务目标 创建模拟网站 创建服务器程序 键盘输入动作 鼠标点击动作 编写爬虫程序 任务目标 Selenium 查找的 HTML 元素是一个 WebElemen t对象&#xff0c; 这个对象不但可以获取元素的属性值&#xff0c;而且还能执行一 些键盘输入send_keys()与鼠标点击click()的动…

Qt画图框架,实现自己的画图框架

前面也讲到Qt提供画图框架&#xff0c;经典MVC模型&#xff0c;也没有什么问题。但Qt仅提供框架性东西&#xff0c;很难落地&#xff0c;很难应用在实际项目当中&#xff0c;一般需要自己捋一遍&#xff0c;这样才能理解好 什么view&#xff0c;canvas都好理解&#xff0c;只要…

Golang内存分配及垃圾回收

为什么需要垃圾回收&#xff1f; 自动释放不需要的对象&#xff0c;让出存储器资源&#xff0c;无需程序员手动执行 Go V1.3之前是标记-清除算法 具体步骤 缺点&#xff1a;程序卡顿、扫描整个heap、数据清除会产生heap碎片 V1.3之后&#xff0c;做了简单的优化 V1.5之后&a…

MySQL索引、事务、与存储引擎

MySQL索引、事务、与存储引擎 一、索引 1.概念 索引是一个排序的列表&#xff0c;包含索引字段的值和其相对应的行数据所在的物理地址2.作用 优点 加快表的查询速度 可以对字段排序缺点 额外占用磁盘空间 更新包含索引的表效率会更慢3.索引工作模式 没有索引的情况下&am…

-1在内存中的存储及打印问题。

首先先看看代码&#xff1a; #include"stdio.h" int main() { char a -1; signed char b -1; unsigned char c -1; printf("a%d b%d c%d", a, b, c); return 0; } 代码很简单&#xff0c;问打印结果是什么&#xff1f; 下面我…

一文了解Python字符串格式化、input语句

目录 &#x1f969;1.1.字符串拼接 &#x1f969;1.2.对字符串格式化 &#x1f969;1.3.字符串精度 &#x1f969;1.4.快速格式化 &#x1f969;1.5.对表达式格式化 &#x1f969;1.6.黑马小练习 &#x1f969;2.1.input语句 &#x1f990;博客主页&#xff1a;大虾好吃吗的博客…

【前端知识】React 基础巩固(十八)——组件化开发(二)

React 基础巩固(十八)——组件化开发&#xff08;二&#xff09; 生命周期 生命周期是一个抽象的概念&#xff0c;在生命周期的整个过程中&#xff0c;分成了很多个阶段 比如装载阶段&#xff08;Mount&#xff09;&#xff0c;组件第一次在 DOM 树中被渲染的过程比如更新过程…

【python】逻辑中断(and or)

今天学习javascript的时候竟然有一个额外收获&#xff1a;逻辑中断。而且我实验了一下&#xff0c;逻辑中断同样适用于python。 0 and 2返回&#xff1a; 0 1 and 2返回&#xff1a; 2 0 and 2返回的是0&#xff0c;而1 and 2返回的是2。就是因为在0那里出现了逻辑中断。 解…