Linux C++ 022-函数模板

Linux C++ 022-函数模板

本节关键字:Linux、C++、函数模板、泛型编程
相关库函数:

函数模板的用法

C++另一种编程思想称为泛型编程,主要利用的技术就是模板,C++提供两种模板机制:函数模板和类模板函数模板的作用:建立一个通用函数,其函数返回值类型和形参类型可以不具体制定,用一个虚拟的类型来代表
template<typename T>

函数声明或定义

template -- 声明创建模板
typename -- 声明其后面的符号是一种数据类型,可以用class代替
T -- 通用的数据类型,名称可以替换,通常为大写字母
// 声明一个模板,告诉编译器后面代码中紧跟着的T不要报错,T是一个通用数据类型
template<typename T>
void mySwap(T &a, T &b)
{T temp = a;a = b;b = temp;
}void test01()
{int a = 10;int b = 20;//1、自动类型推导mySwap(a, b);//2、显示指定类型mySwap<int>(a, b);
}

函数模板总结:

(1)函数模板利用关键字template
(2)使用函数模板有两种方式:自动类型推导、显示指定类型
(3)模板的目的是为了提高复用性,将类型参数化

函数模板注意事项

(1)自动类型推导,必须推导出一致的数据类型T,才可以使用
(2)模板必须要确定出T的数据类型才可以使用

函数模板案例

案例描述:
(1)利用函数模板封装一个排序的函数,可以对不同数据类型数据进行排序
(2)排序规则从大到小,排序算法为选择排序
(3)分别利用char数组和int数组进行测试

// 泛化版本
template<typename T, typename U>
void mySwap(T &a, U &b)
{cout << a << endl;cout << b << endl;
}
//全特化版本,<>内为空
template<>
void mySwap<int, double>(int &a, double &b)
{cout << a << endl;cout << b << endl;
}//class也可换成typename
template<class T>
void mySort(T arr[], int len)
{for(int i=0;i<len;i++){int max = i;for(int j=i+1;j<len;j++){if(arr[max] < arr[j]){max = j;}}if(max != i){mySwap<int>(arr[max], arr[i]);}}
}template<class T>
void printArray(T arr[], int len)
{for(int i=0;i<len;i++){cout << arr[i] << endl;}
}void test01()
{char charArr[] = "abcdef"int num = sizeof(charArr) / sizeof(charArr[0]);mySort<char>(charArr, num);printArray<char>(charArr, num);
}void test02()
{int intArr[] = {1, 2, 4, 3, 6};int num = sizeof(intArr) / sizeof(intArr[0]);mySort<int>(intArr, num);printArray<int>(intArr, num);
}

普通函数与函数模板的区别

(1)普通函数调用时可以发生自动类型转换(隐式类型转换)
(2)函数模板调用时,如果利用自动类型推到,不会发生隐式类型转换
(3)如果利用显示类型的方式,可以发生隐式类型转换

// 普通函数
int mySAdd01(int a, int b)
{return a+b;
}// 函数模板
template<class T>
T myAdd02(T a, T b)
{return a+b;
}// 使用函数模板是,如果用自动类型推导,不会发生自动类型转换,即隐式类型转换
void test01()
{int a = 10;int b = 20;char c= 'c';cout << myAdd01(a, b) << endl; // 30cout << myAdd01(a, c) << endl; // 109cout << myAdd02(a, b) << endl; // 30cout << myAdd02(a, c) << endl; // 报错cout << myAdd02<int>(a, c) << endl; // 109
}
// 建议使用显示指定类型的方式调用函数模板,因为可以自己确定通用类型T

普通函数与函数模板的调用规则

(1)如果函数模板和普通函数都可以实现,优先调用普通函数
(2)可以通过空模板参数列表来强制调用函数模板
(3)函数模板也可以发生重载
(4)如果函数模板可以产生更好的匹配,有限调用函数模板

void myPrint(int a, int b)
{cout << "调用普通函数" << endl;
}template<typename T>
void myPrint(T a, T b)
{cout << "调用函数模板" << endl;
}template<typename T>
void myPrint(T a, T b, T c)
{cout << "调用重载的函数模板" << endl;
}void test01()
{int a = 10;int b = 20;myPrint(a, b); // 调用普通函数myPrint<>(a, b); // 调用函数模板myPrint(a, b, 100); // 调用重载的函数模板
}void test02()
{char a = 'c';char b = 'd';myPrint(a, b); // 调用函数模板
}

总结:既然提供了函数模板,就不要再提供普通函数了,否则容易出现二义性

模板的局限性

模板的通用性并不是万能的,例如:

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

在上述代码中提供的赋值操作,如果传入的a和b是一个数组,就无法实现了,再例如:

template <class T>
void (T a, T b)
{if(a > b){ ... };
}

在上述代码中,如果T的数据类型传入的是像Person这样的自定义数据类型,也无法正常运行,因此C++为了解决这种问题,提供模板的重载,可以为这些特定的类型提供具体化的模板

示例:对比两个数据是否相等的函数

class Person
{
public:person(string name, int age){m_Name = name;m_Age = age;}string m_Name;int m_Age;
};template <class T)
bool myCompare(T &a, T &b)
{if(a == b)return true;elsereturn false;
}void test01()
{int a = 10;int b = 20;bool ret = myCompare(a, b);if(ret)cout << "a = b" << endl;elsecout << "a != b" << endl;
}
void test02()
{Person p1("Tom", 10);Person p2("Tom", 10);bool ret = myCompare(p1, p2);if(ret)cout << "p1 == p2" << endl;elsecout << "p1 != p2" << endl;
}// 利用具体化Person的版本实现代码,具体化 优先使用
template<> bool myCompare(Person &p1, Person p2)
{if(p1.m_Name == p2.m_Name && p1.m_Age == p2.m_Age)return true;elsereturn false;
}

总结

1、利用具体化的模板,可以解决自定义类型的通用化
2、学习模板并不是为了写模板,而是在STL能够运用系统提供的模板

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

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

相关文章

IO流(字节流、字符流)

一、IO概述 1&#xff0e;什么是IO流? 存储和读取数据的解决方案l: inputo: output流∶像水流一样传输数据 2.IO流的作用? 用于读写数据&#xff08;本地文件&#xff0c;网络) 3.IO流按照流向可以分类哪两种流? 输出流:程序 - > 文件 输入流:文件 - > 程…

【解决】安装模块时报错:ERROR: *.whl is not a valid wheel filename.

其实错误信息已经告诉你了&#xff0c;就是你的文件名有问题。在你下载whl文件时一定要注意原文件的文件名&#xff0c;不要改动文件名。 以我安装pandas模块为例吧。 在我下载whl文件时&#xff0c;因为网速太慢&#xff0c;我就下载了多次&#xff0c;导致文件名变成了这个…

ssm044基于java和mysql的多角色学生管理系统+jsp

学生管理系统设计与实现 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本学生管理系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处…

【汇编】计算机系统构成

计算机系统构成 计算机系统包括硬件和软件两部分 硬件 典型的计算机结构包括 中央处理器(CPU)、存储器和输入输出(I/O)子系统 三个主要组成部分&#xff0c;用系统总线把它们连接在一起 计算机硬件组成与各部分之间的联系 软件 计算机软件可以分为系统软件和用户软件两大类 …

redis的缓存击穿、缓存穿透、缓存雪崩

缓存击穿 缓存击穿是指一个key非常热点,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个key在失败的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像在一个完好无损的桶上凿开一个洞。 如何解决 1. 设置热点永不过期 从redis上看,确实没有设置过期时间,这…

Linux系统优化

优化ssh链接速度 xshell中内置了ssh链接的客户端&#xff0c;Linux系统内置了ssh的服务端sshd&#xff0c;默认是开启的&#xff0c;在mac系统中&#xff0c;sshd是默认关闭的&#xff0c;需要手动开启。 [rootlocalhost ~]# ls /etc/ssh moduli sshd_config ssh_…

Monica Unlimited生产环境半年实践心得

程序员开通Monica Unlimited&#xff0c;到现在也有半年&#xff0c;AGI的影响在渐渐发生 最开始的时候并不知道如何和AI协作, 只能逼自己每天和Monica聊天, 但是感觉如果没有目的的提问, 往往也得不到想要的回答. "正则表达式"是kick-Off&#xff0c;学一次用一次的…

Node.js HTTP Server

可以支持视频断点续传。 http-server: a simple static HTTP server # Install npm install --global http-server# cd to targer directory and start http-server

如何查找下载国外博士论文

查找国外博士论文可以去ProQuest学位论文全文数据库&#xff0c;ProQuest学位论文全文数据库&#xff0c;是将ProQuest公司PQDD文摘库&#xff08;现名PQDT&#xff09;中适合中国科研人员科研和教学使用的论文全文建设而成&#xff0c;并向全国百数家科研教学单位的读者提供全…

P1579 哥德巴赫猜想(升级版)Python 埃拉托斯特尼筛法

哥德巴赫猜想&#xff08;升级版&#xff09; 题目背景 1742 年 6 月 7 日&#xff0c;哥德巴赫写信给当时的大数学家欧拉&#xff0c;正式提出了以下的猜想&#xff1a;任何一个大于 9 9 9 的奇数都可以表示成 3 3 3 个质数之和。质数是指除了 1 1 1 和本身之外没有其他约…

【数据结构与算法】贪心算法及例题

目录 贪心算法例题一&#xff1a;找零问题例题二&#xff1a;走廊搬运物品最优方案问题输入样例例题三&#xff1a;贪心自助餐 贪心算法 贪心算法是一种在每一步选择中都采取当前状态下最优的选择&#xff0c;以期望最终达到全局最优解的算法。它的核心思想是每次都选择当前最…

基于动态顺序表的应用——通讯录

文章目录 顺序表的应用——基于动态顺序表实现通讯录一、顺序表的文件&#xff1a;SeqList.hSeqList.c 二、通讯录的实现思路三、通讯录代码实现通讯录的初始化通讯录的销毁通讯录添加数据通过姓名查找联系人通讯录删除数据通讯录展示通讯录修改数据通讯录查找测试代码 四、所有…

R-tree总结

R树&#xff08;R-tree&#xff09;是一种树状数据结构&#xff0c;用于高效地索引和查询多维空间数据。它最常见的应用是在地理信息系统&#xff08;GIS&#xff09;和空间数据库中&#xff0c;用于管理和查询地理空间数据。下面是一个R树的简要总结&#xff0c;并结合一个实际…

永恒之蓝(ms17-010)复现

永恒之蓝 永恒之蓝&#xff08;Eternal Blue&#xff09;爆发于2017年4月14日晚&#xff0c;是一种利用Windows系统的SMB协议漏洞来获取系统的最高权限&#xff0c;以此来控制被入侵的计算机。甚至于2017年5月12日&#xff0c; 不法分子通过改造“永恒之蓝”制作了wannacry勒索…

计算机网络——CSMA/CD协议以及相关习题

目录 前言 引言 CSMA/CD协议 CSMA与CSMA/CD的区别 CSMA/CD流程 前言 本博客是博主用于复习计算机网络的博客&#xff0c;如果疏忽出现错误&#xff0c;还望各位指正。 引言 最早的以太网&#xff0c;许多计算机都连接在一根总线上工作——广播通信方式。 总线的特点想…

2024山东健博会/功能性食品/阿胶/酵素/营养品/肽产品展

2024第6届中国&#xff08;济南&#xff09;国际大健康产业博览会&#xff08;China-DJK山东健博会&#xff09; The 2024 sixth China (Jinan) International Big Health Industry Expo 时间&#xff1a;2024年05月27日—29日 场馆&#xff1a;济南黄河国际会展中心 主办&am…

vim配置 fzf 插件

要配置 fzf 插件&#xff0c;请按照以下步骤进行操作&#xff1a; 安装 fzf&#xff1a;首先&#xff0c;确保你已经安装了 fzf 工具。你可以从 fzf 的 GitHub 页面&#xff08;https://github.com/junegunn/fzf&#xff09;上找到详细的安装指南。 安装 fzf.vim 插件&#xf…

别让这6个UI设计雷区毁了你的APP!

一款成功的APP不仅仅取决于其功能性&#xff0c;更取决于用户体验&#xff0c;这其中&#xff0c;UI设计又至关重要。优秀的UI设计能够为用户带来直观、愉悦的交互体验&#xff0c;甚至让用户“一见钟情”&#xff0c;从而大大提高产品吸引力。 然而&#xff0c;有很多设计师在…

Python的基础知识学习路线2—运算符与变量类型(使用jupyter notebook进行操作:最全路线,每部分附有代码操作结果)

一、更改jupyter notebook 打开文件的位置 1、打开Anaconda Prompt终端&#xff0c;输入以下命令&#xff0c;创建配置文件&#xff1a;jupyter_notebook_config.py jupyter notebook --generate-config2、打开生成的配置文件 3、编辑配置文件jupyter_notebook_config.py&…

获取cookie的方式

获取Cookie的三种方式如下&#xff1a; 使用浏览器开发者工具。打开浏览器的开发者工具&#xff08;例如&#xff0c;Chrome的F12或右键检查&#xff09;&#xff0c;在登录或进行相关操作时&#xff0c;观察Network或XHR标签页中的请求和响应。在请求中查找包含Cookie的…