c++中的模板(2)-- 函数模板(及模板函数)

目录

函数模板: 

语法:

分析:

函数调用: 

怎么实现:   

模板函数: 

函数模板: 

其实就是在函数中使用模板,我们前面的swap函数就是一个函数模板。 

语法:

template <typename 类型名1,typename 类型名2 ...> 

template <typename T>
void Swap(T& a, T& b) {T tmp = a;a = b;b = tmp;
}

分析:

1. template是定义模板的关键字,<>内部用于写类型参数,typename就是用于定义模拟类型的关键字,T就是类型名(类型名的命名方式和变量名的命名方式是一样的,只是习惯使用T,T1等)。

我们定义了模板之后,就可以在下面的函数实现中使用定义的模板类型T了。 这个T可以替换成任意的类型。

2. 定义模板时,<>中的类型参数可以有多个

template <typename T,typename T2>
void printS(T& a,T2& b) {cout << a << endl;cout << b << endl;
}int main(void) {int a = 10;float b = 20.5f;printS(a, b);system("pause");return 0;
}

3. 我们也可以先写函数声明再写函数定义,但是,必须在函数声明和定义前都用该加上模板定义。 

template <typename T,typename T2>
void printS(T& a, T2& b);int main(void) {int a = 10;float b = 20.5f;printS(a, b);system("pause");return 0;
}template <typename T, typename T2>
void printS(T& a, T2& b) {cout << a << endl;cout << b << endl;
}

函数调用: 

对于函数模板,调用函数有两种方式。 

1.  隐式类型参数调用,    调用printS函数: printS(a,b);  编译器会根据我们传入实参的类型,自动将虚拟类型,转换为实参的类型。

2.  显示类型参数调用,  调用printS函数: printS<int,float>(a,b);  我们通过<>中的类型,指定函数模板中虚拟类型指代的具体类型(根据传入类型的顺序,实例化对应虚拟类型)。 

注意:   

定义模板时,  我们会使用到<>,<>和()是类似的。只不过<>中写的是类型参数()中写的是数据参数。在模板定义时, <>中声明类型形参()中声明数据形参

在函数调用时,数据形参的个数有几个,我们就需要传入几个数据实参(使用()传),这样才能正常的调用函数。 类型形参也是类似,我们声明多少个类型形参,在调用函数的时候,就需要传入多少个类型实参(就是具体的类型,使用<>传),否则会报参数不匹配的问题

只不过在一般函数调用的时候,会根据我们传入的实参的类型,编译器会自动实例化声明的虚拟类型。(当然也是同理的,如果有两个虚拟类型,自然需要传入两种类型的数据) 

简单来说,<>和()中都是参数,我们在调用的时候,需要传入对应个数的实参才行。 

// 定义
template <typename T>
void Swap(int& t1, int& t2) {int tmp = t1;t1 = t2;t2 = tmp;
}// 调用
Swap<int>(i1, i2); // 定义
template <typename T,typename T1>
void Swap(int t1[], int t2[], int len) {// 遍历互换for (int i = 0; i < len; i++) {int tmp = t1[i];t1[i] = t2[i];t2[i] = tmp;}
}// 调用
Swap<int,float>(arr1, arr2, len);

上面代码中,即使我们在实现中没有使用定义的虚拟类型。但是我们在<>中声明了类型。就需要在函数调用的时候使用<>显示传入相应的类型。 

注意只有参数使用了相应的模板类型,编译器才能在传参中自动实例化虚拟类型。但是只能实例化参数中使用的虚拟类型。没有使用的,还是需要使用<>传入。 

template <typename T,typename T1>
void Swap(T t1[], T t2[], int len) {// 遍历互换for (int i = 0; i < len; i++) {T tmp = t1[i];t1[i] = t2[i];t2[i] = tmp;}
}// 调用
Swap<int,float>(arr1, arr2, len);

代码中我们即使通过参数实例化了T,但是T1并没有被实例化,所以我们需要显示传入类型实例化T2,但是我们传入时,必须按照声明类型参数的格式进行传参。所以<>中需要传入两个类型分别实例化T1,T2。 

怎么实现:   

那么模板到底是怎么能够实现替换任意类型的呢? 

我们前面说到,在调用模板函数的时候,编译器会根据参数的类型自动转换虚拟类型。 其实模板就是这样,根据我们传入参数的类型,或者传入的类型参数(<>中的),编译器会在内部实现一个相应的函数,然后处理相应的数据。

比如:

template <typename T>
void Swap(T& a, T& b) {T tmp = a;a = b;b = tmp;
}int main(void) {int i1 = 10;int i2 = 20;Swap(i1, i2);/*i1和i2是int类型,编译器会自己转化为一个函数void Swap(int& a, int& b) {int tmp = a;a = b;b = tmp;}*/float f1 = 10.1f;float f2 = 20.1f;Swap(f1, f2);/*f1和f2是float类型,编译器会自己转化为一个和上面同名的Swap重载函数。void Swap(float& a, float& b) {   // 参数不同float tmp = a;a = b;b = tmp;}*/system("pause");return 0;
}

从代码中,注释可以看出来,编译器会根据我们传入的类型,根据函数模板,将相应的虚拟类型替换成我们传入的类型实现一个相应的函数重载。然后再去调用实现相应的功能

模板函数: 

怎么实现中我们说到了,在内部编译器会根据模板实现具体的处理函数。这些编译器实现的处理函数就是模板函数

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

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

相关文章

【MySQL】-17 MySQL综合-3(MySQL创建数据库+MySQL查看数据库+MySQL修改数据库+MySQL删除数据库+MySQL选择数据库)

MySQL创建数据库查看数据库修改数据库删除数据库选择数据库 一 MySQL创建数据库实例1&#xff1a;最简单的创建 MySQL 数据库的语句实例2&#xff1a;创建 MySQL 数据库时指定字符集和校对规则 二 MySQL查看或显示数据库实例1&#xff1a;查看所有数据库实例2&#xff1a;创建并…

go常见问题

1、go : 无法将“go”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写&#xff0c;如果包括路径&#xff0c;请确保路径正确&#xff0c;然后再试一次。 所在位置 行:1 字符: 1 解决方式&#xff1a;$env:Path [System.Environment]::GetEnvironmentVa…

【Network Management】AUTOSAR架构下CanNm User Data详解

目录 前言 正文 1.CanNm user data概念 2.CanNm user data配置 2.1CDD方式访问CanNm user data

神经网络(Nature Network)

最近接触目标检测较多&#xff0c;再此对最基本的神经网络知识进行补充&#xff0c;本博客适合想入门人工智能、其含有线性代数及高等数学基础的人群观看 1.构成 由输入层、隐藏层、输出层、激活函数、损失函数组成。 输入层&#xff1a;接收原始数据隐藏层&#xff1a;进行…

Clickhouse查询语句执行过程

问题 简述clickhosue中一条select语句的执行过程&#xff0c;使用的引擎是ReplacingMergeTree。例如&#xff1a; select col1,col2 from table final prewhere col3 > ? and col4 ? and col5 ? -- col3为分区键&#xff0c;col4为二级索引,col5为主键字段 where col…

Stable Diffusion 模型下载:Disney Pixar Cartoon Type B(迪士尼皮克斯动画片B类)

本文收录于《AI绘画从入门到精通》专栏,专栏总目录:点这里。 文章目录 模型介绍生成案例案例一案例二案例三案例四案例五案例六案例七案例八案例九案例十

阿里云服务器带宽计费模式是什么?怎么选择?

阿里云服务器带宽计费模式分为“按固定带宽”和“按使用流量”&#xff0c;有什么区别&#xff1f;按固定带宽是指直接购买多少M带宽&#xff0c;比如1M、5M、10M、100M等&#xff0c;阿里云直接分配用户所购买的带宽值&#xff0c;根据带宽大小先付费再使用&#xff1b;按使用…

Windows Server 2019 搭建并加入域

系列文章目录 目录 系列文章目录 文章目录 前言 一、域是什么&#xff1f; 二、配置服务器 1.实验环境搭建 1)实验服务器配置和客户端 2)实验环境 2.服务器配置 账户是域服务器的账户和密码 文章目录 Windows Server 2003 Web服务器搭建Windows Server 2003 FTP服务器搭…

Hadoop:认识MapReduce

MapReduce是一个用于处理大数据集的编程模型和算法框架。其优势在于能够处理大量的数据&#xff0c;通过并行化来加速计算过程。它适用于那些可以分解为多个独立子任务的计算密集型作业&#xff0c;如文本处理、数据分析和大规模数据集的聚合等。然而&#xff0c;MapReduce也有…

1306. 跳跃游戏 III

经过测试&#xff0c;两种写法耗时差距10倍&#xff0c;我也不知道原因是啥 用访问次数的是更快的 class Solution { public:int n;bool dfs(vector<int>& arr, int start, vector<int>& visited){if(start<0||start>n || visited[start]1) return …

每日OJ题_位运算⑤_力扣371. 两整数之和

目录 力扣371. 两整数之和 解析代码 力扣371. 两整数之和 371. 两整数之和 难度 简单 给你两个整数 a 和 b &#xff0c;不使用 运算符 和 - &#xff0c;计算并返回两整数之和。 示例 1&#xff1a; 输入&#xff1a;a 1, b 2 输出&#xff1a;3示例 2&#xff1a; …

c++中的模板(4)-- 类模板

和函数模板类似&#xff0c;类也可以使用模板。 类模板 使用template <typename T ...> class A{} &#xff0c;这样就声明了一个类模板。我们就可以在成员函数和成员属性中使用虚拟类型T了 1. 成员函数在类内部进行实现 /*类模板 */ template <typename T> …

《UE5_C++多人TPS完整教程》学习笔记4 ——《P5 局域网连接(LAN Connection)》

本文为B站系列教学视频 《UE5_C多人TPS完整教程》 —— 《P5 局域网连接&#xff08;LAN Connection&#xff09;》 的学习笔记&#xff0c;该系列教学视频为 Udemy 课程 《Unreal Engine 5 C Multiplayer Shooter》 的中文字幕翻译版&#xff0c;UP主&#xff08;也是译者&…

【求助帖】22届失业5个月了,第一份工作被坑,现在科班出身却没offer,我该怎么办

【我是谁】 1.学历&#xff1a;22届双非本科校企合作&#xff08;软外&#xff0c;软件工程服务外包&#xff09;&#xff0c;编程课大部分是印度的NIIT老师上课&#xff0c;印式英语一点儿听不懂。。。所以大学全都自学的&#xff0c;和非科班的也没什么区别和优势&#xff0c…

Java 学习和实践笔记(6)

各数据类型所占的空间&#xff1a; byte: 1个字节 short&#xff1a;2个字节 int&#xff1a;4个 long&#xff1a;8个 float&#xff1a;4个 double: 8个 char:1个 boolean:1bit 所有引用数据类型都是4个字节&#xff0c;实际其值是指向该数据类型的地址。 上图中稍特…

blender怎么保存窗口布局,怎么设置默认输出文件夹

进行窗口布局大家都会&#xff0c;按照自己喜好来就行了&#xff0c;设置输出文件夹如图 这些其实都简单。关键问题在于&#xff0c;自己调好了窗口布局&#xff0c;或者设置好了输出文件夹之后&#xff0c;怎么能让blender下次启动的时候呈现出自己设置好的窗口布局&#xff…

【开源】SpringBoot框架开发木马文件检测系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 木马分类模块2.3 木马软件模块2.4 安全资讯模块2.5 脆弱点模块2.6 软件检测模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 木马分类表3.2.2 木马软件表3.2.3 资讯表3.2.4 脆弱点表3.2.5 软件检测表…

有人说可视化大屏是讨好领导的,有错么?难道讨好你这个大头兵

最近我分享了一批大数据可视化的界面&#xff0c;大部分粉丝都是认可的&#xff0c;也有粉丝想不到这个有啥用&#xff0c;极个别人非常酸&#xff0c;认为这个除了讨好领导&#xff0c;屁用没有。 客户既然花大钱找我们&#xff0c;肯定有用处。 首先&#xff0c;这里我给解…

线程的基础-线程和进程、并行与并发

线程和进程的区别&#xff0c;简单理解就是电脑一个完整的任务就是一个进程&#xff0c;一个进程可有多可线程组成&#xff0c;多个线程都是这个任务的组成部分共享资源。 进程是程序在执行过程中的一个实例,它拥有独立的内存空间和系统资源,而线程是进程的一个执行单元,是进程…

【C++】强制类型转换

强制类型转换分为显式和隐式 显式直接用小括号强制转换&#xff0c;float b (int)a; 隐式直接 float b 0.5; int a b; C中更推荐用四个强制类型转换的关键字&#xff1a; 1、static_cast&#xff0c; 2、const_cast&#xff0c; 3、reinterpret_cast&#xff0c; 4、dynami…