【C++奇遇记】函数模板

🎬 博客主页:博主链接
🎥 本文由 M malloc 原创,首发于 CSDN🙉
🎄 学习专栏推荐:LeetCode刷题集 数据库专栏 初阶数据结构
🏅 欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!
📆 未来很长,值得我们全力奔赴更美好的生活✨

在这里插入图片描述
在这里插入图片描述

文章目录

  • 😇本章详情
  • 😇函数模板的前情介绍
  • 😇利用函数模板来定义交换函数
    • 📝建立交换模板
  • ✉重载的模板
  • 📋模板的局限性
  • 😇显示具体化
  • 📃如何巩固学习
  • 📃本文小结

😇本章详情

🐤本篇文章将讲授C++的函数模板相关的知识

😇函数模板的前情介绍

😁现在的C++编译器实现了C++新增的一项特性—函数模板。函数模板。函数模板是通用的函数描述,也就是说,它们使用泛型来定义函数,其中的泛型可用具体的类型(如int或double)替换。通过将类型作为参数传递给模板,可使编译器生成该类型的函数。由于模板允许以泛型(而不是具体类型)的方式编写程序,因此有时也被称为通用编程。由于类型是用参数表示的,因此模板特性有时也被称为参数化类型。

😇利用函数模板来定义交换函数

📝建立交换模板

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

解析

第一行指出,要建立一个模板,并将类型命名为T。关键字template和typename是必需的,除非可以使用关键字class代替typename。另外,必须使用尖括号。类型名可以任意选则(这里为T),只要遵守C++命名规则即可。模板并不创建任何函数,而只是告诉编译器如何定义函数。需要交换int的函数时,编译器将按模板模式创建这样的函数,并用int代替T。同样交换double的函数时,编译器将按模板模式创建这样的函数,并有double代替T。


C++98之前的定义方式
在标准C++98添加关键字typename之前,C++使用关键字class来创建模板

template<class T>
void swap(T& a,T& b)
{T temp;temp = a;a = b;b = temp;
}

typename关键字使得参数T表示类型这一点更为明显;然而,有大量的代码库是使用关键字class开发的。这两种关键字等价的。

✉重载的模板

💐需要多个对不同类型使用同一种算法的函数时,可使用模板,然而并且所有的类型都使用相同的算法。为满足这种需求,可以向重载常规函数定义那样重载模板定义。和常规重载一样,被重载的模板的函数特征标必须不同。例如,在下方代码中新增了一个交换模板,用于交换两个数组中的元素。原模板的特征标为(T&, T&),而新模板的特征标为(T[], T[], int)。在后一个模板中,最后一个参数的类型为具体类型int,而不是泛型。并非所有的模板参数都必须是模板参数类型。


代码演示

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<list>
using namespace std;
template <typename T>
void Swap(T& a,T& b);// new templatetemplate template <typename T>
void Swap(T *a,T *b,int n);void Show(int a[]); 
const int Lim = 8; 
int main()
{int i = 10, j = 20;cout << "i, j =" << i << ", " << j << "\n";Swap(i, j);cout << i << j << endl;int d1[Lim] = { 0,7,0,4,1,7,7,6 };int d2[Lim] = { 0,7,2,0,1,9,6,9 };cout << "original arrays:\n";Show(d1);Show(d2);Swap(d1, d2, Lim);cout << "Swapped array:\n";Show(d1);Show(d2);return 0;
}
template <typename T>
void Swap(T& a, T& b)
{T temp;temp = a;a = b;b = temp;
}template <typename T>
void Swap(T a[], T b[], int n)
{T temp;for (int i = 0; i < n; i++){temp = a[i];a[i] = b[i];b[i] = temp;}
}void Show(int a[])
{cout << a[0] << a[1] << "/";cout << a[2] << a[3] << "/";for (int i = 4; i < Lim; i++){cout << a[i];}cout << endl;
}

输出
在这里插入图片描述

📋模板的局限性

💐假设有如下模板函数:

template <class T>
void f(T a,T b)
{}

通常,代码假定可执行那些操作。例如,下面的代码假定定义了赋值,但
如果T为数组,这种假设将不成立:

a = b

同样,下面的语句假设定义了>,但如果T 为结构,该假设便不成立:

if(a>b)

另外,为数组名定义了运算符>,但由于数组名为地址,因此他比较的是数组的地址,而这可能不是您希望的。

注意

名称空间可以是全局的,也可以位于另一个名称空间中,但不能位于代码块中。因此,在默认的情况下,在名称空间中声明的名称的链接性为外部的(除非它引用了常量)

😇显示具体化

📖假设定义了如下结构:

struct job
{char name[40];double salary;int floor;-
};

🌼;另外,假设希望能够交换两个这种结构的内容。原来的模板使用下面的代码来完成交换:

temp = a;
a = b;
b = temp;

由于C++允许将一个结构赋给另一个结构,因此即使T是一个job结构,上述代码也适用。然而,假设只想交换salary和floor成员,而不交换name成员,则需要使用不同的代码,但Swap()的参数将保持不变(两个job结构的引用),因此无法使用模板重载来提供其他的代码。

然而,可以提供一个具体化函数定义----称为显示具体化(explicit specialization),其中包含所需的代码。当编译器找到与函数调用匹配的具体化定义时,将使用该定义,而不再寻找模板。


第三代具体化(ISO/ANSI C C++标准)

  1. 对于给定的函数名,可以有非模板函数、模板函数和显式具体化模板函数以及它们的重载版本。
  2. 显式具体化的原型和定义应以template<>打头,并通过名称来指出类型。
  3. 具体化优先于常规模板,而非模板函数优先于具体化和常规模板

下面是用于交换job结构的非模板函数、模板函数和具体化的原型:

void Swap(job &, job &);template <typename T>
void Swap(T&, T&);template <> void Swap<job>(job&, job&);

📃如何巩固学习

提示:在学习的过程中,我们需要先自行进行思考,并且多去阅读一些大佬的书籍,俗话说的好,书籍是人类进步的阶梯!

📃本文小结

  1. C++鼓励程序员在开发程序时使用多个文件。一种有效的组织策略是,使用头文件来定义,为操纵用户类型的函数提供函数原型;并将函数定义放在一个独立的源代码文件中。头文件和源代码文件一起定义和实现了用户定义的类型及其使用方式。最后,将main()和其他使用这些函数的函数放在第三个文件中。

好啦今日的分享到这里就结束啦,我是爱你们的M malloc希望可以帮助到你们噢,最后别忘记三连啦!!

在这里插入图片描述

在这里插入图片描述

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

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

相关文章

【LeetCode-中等题】238. 除自身以外数组的乘积

题目 题解一&#xff1a;暴力双指针—超时了 双指针暴力查找(需考虑begin end 和begin end i) 的情况 ----- 力扣示例超出时间限制 public int[] productExceptSelf(int[] nums) {int length nums.length;int begin 0;int end length -1;int i 0;int[] number new in…

【C++心愿便利店】No.2---函数重载、引用

文章目录 前言&#x1f31f;一、函数重载&#x1f30f;1.1.函数重载概念&#x1f30f;1.2.C支持函数重载的原理 -- 名字修饰 &#x1f31f;二、引用&#x1f30f;2.1.引用的概念&#x1f30f;2.2.引用特性&#x1f30f;2.3.常引用&#x1f30f;2.4.使用场景&#x1f30f;2.5.传…

手机自动无人直播,实景无人直播真的有用吗?

继数字人直播之后&#xff0c;手机自动直播开始火热了起来&#xff0c;因为其门槛低&#xff0c;成本低&#xff0c;一部手机一个账号就可以实现直播&#xff0c;一时深受广大商家的好评。那么&#xff0c;手机自动无人直播究竟是如何实现自动直播的呢&#xff1f; 在传统的直…

P14-CVPR2022-1.0-RepLKNet31

论文地址:https://arxiv.org/abs/2203.06717 代码地址:GitHub - MegEngine/RepLKNet: Official MegEngine implementation of RepLKNet ‘ 目录 Abstract 一.Introduction 二.Related Work 2.1Model with Large Kernels 2.2Model Scaling Techniques 2.3Structural Re-…

vue-element-admin最新版4.4实现多个url路由匹配到一个路径时,左侧菜单保持高亮状态

文章目录 环境&#xff1a;需求&#xff1a;原因分析&#xff1a;如何解决&#xff1a; 环境&#xff1a; vue-admin-template-4.4版本&#xff08;vue2&#xff09; 需求&#xff1a; 当我访问申请开户时&#xff0c;也希望支付菜单能保持高亮状态。 原因分析&#xff1a; …

SpringMVC-2-Spring MVC拦截器详解:从入门到精通

SpringMVC-2-Spring MVC拦截器详解&#xff1a;从入门到精通 今日目标 能够编写拦截器并配置拦截器 1.拦截器【理解】 1 拦截器介绍 1.1 拦截器概念和作用 拦截器&#xff08;Interceptor&#xff09;是一种动态拦截方法调用的机制&#xff0c;在SpringMVC中动态拦截控制器方…

PHP实践:手把手微信公众号网页授权登录功能实现

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;全栈领域新星创作者✌&#xff0c;CSDN博客专家&#xff0c;阿里云社区专家博主&#xff0c;2023年6月CSDN上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责…

【2023深圳杯数学建模A题思路模型与代码分享】

2023深圳杯数学建模A题 A题 影响城市居民身体健康的因素分析解题思路第一问第二问第三问第四问 技术文档第一问完整代码写在最后 A题 影响城市居民身体健康的因素分析 以心脑血管疾病、糖尿病、恶性肿瘤以及慢性阻塞性肺病为代表的慢性非传染性疾病&#xff08;以下简称慢性病…

SQL注入读写文件

文章目录 条件利用SQL注入漏洞读取hosts文件查看文件读写权限安全选项允许导入导出读取hosts文件 利用SQL注入漏洞写入一句话木马&#xff0c;并用蚁剑连接webshell写入文件 条件 SQL注入有直接SQL注入&#xff0c;也有文件读写时的注入&#xff0c;后者的主要 目的在于获取web…

探讨uniapp的页面问题

1 新建页面 uni-app中的页面&#xff0c;默认保存在工程根目录下的pages目录下。 每次新建页面&#xff0c;均需在pages.json中配置pages列表&#xff1b; 未在pages.json -> pages 中注册的页面&#xff0c;uni-app会在编译阶段进行忽略。pages.json的完整配置参考&am…

APSIM模型应用与参数优化、批量模拟

APSIM (Agricultural Production Systems sIMulator)模型是世界知名的作物生长模拟模型之一。APSIM模型有Classic和Next Generation两个系列模型&#xff0c;能模拟几十种农作物、牧草和树木的土壤-植物-大气过程&#xff0c;被广泛应用于精细农业、水肥管理、气候变化、粮食安…

【动手学深度学习】--18.图像增广

文章目录 图像增广1.常用的图像增广方法1.1翻转和裁剪1.2改变颜色1.3结合多种图像增广方法 2.使用图像增广进行训练3.训练 图像增广 官方笔记&#xff1a;图像增广 学习视频&#xff1a;数据增广【动手学深度学习v2】 图像增广在对训练图像进行一系列的随机变化之后&#xff…