c++中的模板(3) -- 函数模板和函数重载

目录

分析: 

函数模板重载 

分析: 

前面说到,模板的存在可以替换所有的类型,那么如果我们写了函数模板之后,还能否写(同名)具体类型的函数了并且在写了之后,如果我们调用这个函数是调用函数模板还是具体的函数?

/*函数模板
*/
template <typename T>
const T& Max(const T& t1,const T& t2) {if (t1 == t2) {return t1;}cout << "const T& Max(const T& t1,const T& t2)" << endl;return t1 > t2 ? t1 : t2;
}/*具体类型函数
*/
const int& Max(const int& i1, const int& i2) {if (i1 == i2) {return i1;}cout << "const int& Max(const int& i1, const int& i2)" << endl;return i1 > i2 ? i1 : i2;
}int main(void) {int i1 = 10;int i2 = 20;Max(i1, i2);   // 调用情况: const int& Max(const int& i1, const int& i2)float f1 = 15.5f;float f2 = 16.6f;Max(f1, f2);   //  const T& Max(const T& t1,const T& t2)char c1 = 'a';char c2 = 'd';Max(c1, c2);   //  const T& Max(const T& t1,const T& t2)system("pause");return 0;
}

分析: 

1.  我们分别使用模板和具体类型(int 类型)实现Max()的函数。 然后我们在main函数中调用函数。

会发现:   当我们传入的值为int类型的时候,会调用具体类型实现的Max()函数,而当我们使用其它的类型的时候,就会调用函数模板。

总结:     

1)  首先函数重载和函数模板可以同时存在。 

2)  如果我们传入的数据类型和普通函数中的参数类型完全一致,那么就优先调用具体类型的函数实现。

3)  如果传入的数据类型和普通函数中的参数类型不一样(即使,传入的类型和参数类型可以默认转换, 如: char -> int),那也会优先调用函数模板。  

4)  我们在模板定义时,我们定义了一个虚拟类型T,这也就是说,在这个函数模板中使用到虚拟类型T的都是同一个类型。所以,如果我们传入的参数是一个int,一个char,那么此时会调用普通类型的函数实现

因为:   我们定义的函数模板只有一个虚拟类型名T,也就是参数中的参数类型,只有一种。但是我们传入的是char和int两种类型,所以和函数模板的参数类型不匹配

但是, 我们定义的普通类型函数的参数是int类型的,char类型可以隐式转换为int类型,所以这时候会调用普通类型函数。

5)所以,1.如果传入的参数和普通函数完全一致,优先调用普通函数实现。

                2.如果传入的参数和普通函数不一致,但是符合函数模板的参数要求,则调用函数模板。

                3.如果传入的参数和普通函数和函数模板的参数都不一致,但是传入参数可以隐式转换为普通函数的参数类型,那么调用普通函数实现。 

 

函数模板重载 

 函数模板和函数重载是可以共存的,那么函数模板能不能进行重载呢?  答案是,肯定的。

实际说来,函数模板也是函数,只是编译器帮助我们实现了而已。前面使用函数模板将Swap()函数由多个写为了一个,但是前提是函数的函数实现中除去类型的差距其余都是一样的。 

如果我们想要使用相同的模板函数名实现不同的功能,这时候就需要用到函数模板的重载了。 函数模板的重载和普通函数的重载是类似的,都是根据参数进行区别的。

/*模板函数交换一般数据的值
*/
template <typename T>
void Swap(T& t1, T& t2) {T tmp = t1;t1 = t2;t2 = tmp;
}/*模板函数交换数组中的数据
*/
template <typename T>
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;}
}template <typename T>
void printA(T t1[], int len) {for (int i = 0; i < len; i++) {cout << t1[i] << " ";}cout << endl;
}int main(void) {int i1 = 10;int i2 = 20;Swap(i1, i2);   // 调用情况: const int& Max(const int& i1, const int& i2)int arr1[] = {1,2,3,4,5};int arr2[] = { 6,7,8,9,10 };int len = sizeof(arr1) / sizeof(arr1[0]);Swap(arr1, arr2, len);printA(arr1, len);printA(arr2, len);system("pause");return 0;
}

分析: 

1.  我们之前实现的交换数据,只能实现普通的类型进行互换,如果是数组中的数据进行互换,直接arr1 = arr2,这是不正确的。 对数组进行互换,我们需要遍历数组中的每个元素,然后逐一互换。

2.  但是我们前面实现的函数模板自然就不适合数组互换了,所以我们需要对Swap函数进行重载,将函数模板的内部的代码重新实现。以支持数组数据的互换。 

3.  int a[10]中,数组a是int [10]的类型的。我们在模板参数中如果直接写成T t,那替换过来就是int [10]a,这样写显然不正确,所以我们应该写成T t1[],或者使用指针或者引用。其实和一般情况下,数组传参数的一样的

4.   代码中,函数模板中的参数,不一定都需要使用虚拟类型,也可以包括一般类型。

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

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

相关文章

【北邮鲁鹏老师计算机视觉课程笔记】04 fitting 拟合

【北邮鲁鹏老师计算机视觉课程笔记】04 fitting 拟合 1 拟合的任务 如何从边缘找出真正的线&#xff1f; 存在问题 ①噪声 ②外点、离群点 ③缺失数据 2 最小二乘 存在的问题 3 全最小二乘 度量的是点到直线的距离而不是点在y方向到直线的距离 提示&#xff1a;点到直线的…

git的操作(Operation of Git)

下载git&#xff0c;以archlinux为例&#xff1a;yay -S git git分为三个区 暂存区&#xff1a;工作区的变更提交到暂存区 工作区&#xff1a;存放文件的地方 版本库&#xff1a;暂存区的内容提交到版本库 # 新建 # 在当前目录初始化git代码库 git init # 将指定目录新建并…

Golang开发:跨域配置

跨域中间件 /lib/middleware/crossorigin_mv.go package middlewareimport ("github.com/gin-gonic/gin""net/http" )/*** 跨域设置*/ func CrossOriginMiddleware() gin.HandlerFunc {return func(context *gin.Context) {method : context.Request.Met…

Educational Codeforces Round 135 (Rated for Div. 2)C. Digital Logarithm(思维)

文章目录 题目链接题意题解代码 题目链接 C. Digital Logarithm 题意 给两个长度位 n n n的数组 a a a、 b b b&#xff0c;一个操作 f f f 定义操作 f f f为&#xff0c; a [ i ] f ( a [ i ] ) a [ i ] a[i]f(a[i])a[i] a[i]f(a[i])a[i]的位数 求最少多少次操作可以使 …

操作系统基础:IO核心子系统【下】

&#x1f308;个人主页&#xff1a;godspeed_lucip &#x1f525; 系列专栏&#xff1a;OS从基础到进阶 &#x1f3c6;&#x1f3c6;本文完整PDF源文件请翻阅至文章底部下载。&#x1f3c6;&#x1f3c6; ⚕️1 I/O核心子系统——概述&#x1f531;1.1 核心子系统要完成的功能…

视觉SLAM十四讲学习笔记(二)三维空间刚体

哔哩哔哩课程连接&#xff1a;视觉SLAM十四讲ch3_哔哩哔哩_bilibili​ 目录 一、旋转矩阵 1 点、向量、坐标系 2 坐标系间的欧氏变换 3 变换矩阵与齐次坐标 二、实践&#xff1a;Eigen&#xff08;1&#xff09; 运行报错记录与解决 三、旋转向量和欧拉角 1 旋转向量 …

速盾:怎么拿高防服务器做CDN

想要拿高防服务器做CDN&#xff0c;首先需要了解什么是CDN。CDN&#xff0c;即内容分发网络&#xff08;Content Delivery Network&#xff09;&#xff0c;是一种通过互联网连接多个服务器&#xff0c;将静态和动态内容分发到最接近用户的服务器节点&#xff0c;从而提高用户访…

备份还原实际操作

备份还原实际操作 前言 根据达梦文档整理。 一、工具介绍 工具联机/脱机工具应用场景disql联机1️⃣数据库备份2️⃣归档备份3️⃣表空间备份与还原4️⃣表备份与还原dmrman脱机1️⃣数据库备份、还原和恢复2️⃣脱机还原表空间3️⃣归档的备份、还原和修复manager联机对应…

Rust引用、借用和所有权详解

在Rust中&#xff0c;引用、借用和所有权是语言的核心概念&#xff0c;它们共同构成了内存管理的基石。本篇博客将介绍Rust中的这些概念&#xff0c;并通过具体的例子深入探讨它们的用法和优势。 所有权 Rust中的所有权是一种独特的内存管理机制&#xff0c;它规定了在特定作…

协议-TCP协议-基础概念04-可能发生丢包的位置-linux配置项梳理(TCP连接的建立和断开、收发包过程)

可能发生丢包的位置-linux配置项梳理&#xff08;TCP连接的建立和断开、收发包过程&#xff09;-SYN Flood攻击和防御原理 参考来源&#xff1a; 极客时间-Linux性能优化实战 极客时间-Linux内核技术实战课 到底是哪里发生了丢包呢&#xff1f; Linux 的网络收发流程 从图中…

【java】笔记10:类与对象——本章练习

题目1&#xff1a; 代码如下&#xff1a; import java.util.Scanner; public class Input{public static void main(String[]args){Circle cnew Circle();PassObject yuannew PassObject();System.out.println("r""\t""times");yuan.printAreas…

缓存穿透问题与解决方案

引言 在分布式系统中&#xff0c;缓存技术被广泛应用以提高系统性能和响应速度。然而&#xff0c;缓存穿透是一个常见而严重的问题&#xff0c;特别是在面对大规模请求时。本文将深入探讨缓存穿透的原因、影响以及一些有效的解决方案&#xff0c;以确保系统在面对这一问…

【Effective Objective - C 2.0】——读书笔记(三)

文章目录 十五、用前缀避免命名空间冲突十六、提供全能初始化方法十七、实现description方法十八、尽量使用不可变对象十九、使用清晰而协调的命名方式二十、为私有方法名加前缀二十一、理解Objective-C错误模型二十二、理解NSCopying协议 十五、用前缀避免命名空间冲突 OC语言…

1+X运维试题样卷D卷(初级)

云计算D卷 单选题(200分) 1.以下哪一项最好地描述了何时完成监控项目过程组?(10分) (答案正确:10分) A、整个项目中持续进行 (正确答案) B、每个可交付成果完成时 C、计划里程碑或项目间隙 D、每个项目阶段结束时 2.以下哪一个是收尾过程的正确顺序?(10分) (答案错误:0分…

2023年股市总结,2024年A股方向展望!

2023年股市总结&#xff0c;2024年A股方向展望&#xff01; 随着2023年的结束&#xff0c;让我们回顾一下这一年的股市表现。在全球经济复苏的大背景下&#xff0c;2023年的股市呈现出波动上涨的趋势。 全球股市概述 在2023年&#xff0c;全球股市经历了许多变化。各国经济逐…

KingSCADA实现按钮点击效果

哈喽&#xff0c;你好啊&#xff0c;我是雷工&#xff01; 在做SCADA项目的时候&#xff0c;按钮是不可缺少的功能&#xff0c;但软件自带的按钮太丑&#xff0c;已经无法满足现如今客户对界面美观度的要求。 这时候就需要UI小姐姐设计美观大气的SCADA界面&#xff0c;但UI设计…

蓝牙BLE学习

1. 简介 1.1 蓝牙发展历程 蓝牙&#xff0c;直接来自于一位国王的名字--King Harald ‘Bluetooth Gromsson。这位国王因两件事留名于史&#xff0c;其一是在公园958年统一了丹麦和挪威&#xff0c;其二是在其死后&#xff0c;其牙齿呈现出暗蓝色的颜色&#xff0c;因而得名蓝牙…

第74讲Breadcrumb 面包屑实现

Breadcrumb 面包屑实现 为了实现二级路由&#xff0c;我们搞成搞个子路由&#xff0c;对于二级菜单 const routes [{path: /,name: 首页,component: () > import(../views/layout),redirect:/home,children:[{path: /home,name: 首页,component: () > import(../views…

《UE5_C++多人TPS完整教程》学习笔记10 ——《P11 设置加入游戏会话(Setup for Joining Sessions)》

本文为B站系列教学视频 《UE5_C多人TPS完整教程》 —— 《P11 设置加入游戏会话&#xff08;Setup for Joining Sessions&#xff09;》 的学习笔记&#xff0c;该系列教学视频为 Udemy 课程 《Unreal Engine 5 C Multiplayer Shooter》 的中文字幕翻译版&#xff0c;UP主&…

Git Push -f 命令详解

直接看原文: Git Push -f 命令详解 - 玩转Linux - SegmentFault 思否 -------------------------------------------------------------------------------------------------------------------------------- git push -f 这个命令的作用是将自己本地仓库的代码直接推送至仓…