当前位置:网站首页>函数模板的系列操作( 详解 )
函数模板的系列操作( 详解 )
2022-07-16 14:30:00 【比特冬哥】
一、函数模板简介
函数模板不是一个实在的函数,编译器不能为其生成可执行代码。定义函数模板后只是一个对函数功能框架的描述,当它具体执行时,将根据传递的实际参数决定其功能。
函数模板可以用来创建一个通用的函数,以支持多种不同的形参,避免重载函数的函数体重复设计。它的最大特点是把函数使用的数据类型作为参数。
函数模板的声明形式为:
template<typename 数据类型参数标识符>
<返回类型><函数名>(参数表)
{
函数体
}
其中,template是 定义模板函数的关键字;template后面的尖括号不能省略;typename(或class)是声明数据类型参数标识符的关键字,用以说明它后面的标 识符是数据类型标识符。这样,在以后定义的这个函数中,凡希望根据实参数据类型来确定数据类型的变量,都可以用数据类型参数标识符来说明,从而使这个变量 可以适应不同的数据类型。
二、具体使用
1. 基本语法
//交换整数型函数
void swapInt(int &a,int &b)
{
int temp=a;
a=b;
b=temp;
}
//交换浮点型函数
void swapDouble(double &a,double &b)
{
double temp=a;
a=b;
b=temp;
}
//利用模板提供通用的交换函数
template<typename T> //typename可以替换成 class
void mySwap(T &a,T &b)
{
T temp=a;
a=b;
b=temp;
}
test01()
{
int a=10;
int b=20;
// swapInt(a,b);
//利用模板实现交换
//1、自动类型推导
mySwap(a,b);
//2、显示指定类型
// mySwap<int>(a,b);
cout<<"a = "<<a<<endl;
cout<<"b = "<<b<<endl;
}
2. 注意事项
//注意事项:
// 1、自动类型推导,必须推导出一致的数据类型T,才可以使用
// 2、模板必须要确定出T的数据类型,才可以使用
//利用模板函数提供通用的交换函数
template<typename T> //typename可以替换成 class
void mySwap(T &a,T &b)
{
T temp=a;
a=b;
b=temp;
}
//自动类型推导,必须推导出一致的数据类型T,才可以使用
void test01()
{
int a=10;
int b=20;
char c='c';
mySwap(a,b); //正确,可以推导出一致的T
// mySwap(a,c); //错误,推导不出一致的T类型
}
// 模板必须要确定出T的数据类型,才可以使用
template<class T>
void func()
{
cout<<"func调用"<<endl;
}
void test02()
{
// func(); //错误,模板不能独立使用,必须确定出T的类型
func<int>(); //利用显示指定类型的方式,给T一个类型,才可以使用改模板
}
3. 普通函数与函数模板的调用规则
//普通函数和函数模板的调用规则
// 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;
int c=30;
char c1='a';
char c2='b';
myPrint(a,b); // 1、如果函数模板和普通函数都可以实现,优先调用普通函数
myPrint<>(a,b); // 2、可以通过空模板参数列表来 强制调用函数模板
myPrint(a,b,c); // 3、函数模板也可以发生重载
myPrint(c1,c2); // 4、如果函数模板可以产生更好的匹配 优先调用函数模块
}
4. 普通函数与函数模板的区别
//普通函数与函数模板的区别
// 1、普通函数调用可以发生隐式类型转换
// 2、函数模板 用自动类型推导,不可以发生隐式类型转换
// 3、函数模板 用显示指定类型,可以发生隐式类型转换
//普通函数
int myAdd01(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'; //a - 97 , c - 99
cout<<myAdd01(a,c)<<endl; //会自动给字符‘c’ 转换为ASCII码 99 进行相加
//自动类型推导 不会发生隐式类型转换
// cout<<myAdd02(a,c)<<endl; //报错,因为字符'c' 函数模块不知道转换为int 还是 char
//显示指定类型 会发生隐式类型转换
cout<<myAdd02<int>(a,c)<<endl; //会将字符'c' 转换成int型
}
三、案列 - 数组排序
#include<iostream>
#include<string>
using namespace std;
//实现通用 对数组进行排序的函数
//规则 从大到小
//算法 选择
//测试 char数组、int数组
//交换函数模板
template<typename T> //typename可以替换成 class
void mySwap(T &a,T &b)
{
T temp=a;
a=b;
b=temp;
}
//排序算法
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(arr[max],arr[i]);
}
}
}
//提供打印数组模板
template<class T>
void printArray(T arr[],int len)
{
for(int i=0;i<len;i++)
{
cout<<arr[i]<<" ";
}
cout<<endl;
}
// 测试char数组
void test01()
{
char charArr[]="badfec";
int len=sizeof(charArr)/sizeof(char);
mySort(charArr,len);
printArray(charArr,len);
}
// 测试int数组
void test02()
{
int intArr[]={
2,5,1,6,8,4,7,5,0,1,3};
int len=sizeof(intArr)/sizeof(int);
mySort(intArr,len);
printArray(intArr,len);
}
int main()
{
test01();
test02();
system("pause");
return 0;
}
边栏推荐
- 标准输入输出流
- Error :Could not decode ...With “UTF-8“-encoding. Editing not possible
- 2022.7.15-----leetcode.558
- Pytorch构建网络细节总结
- WordPress personal blog theme wp-reason-v1.0
- Bean的生命周期详解
- 【Ucos-III源码分析】——事件标志组
- 【纪中】2022.7.13 3058.火炬手
- [product people Wei Peng] 13 design websites necessary for product people in 2022 (version 1.0)
- STM32 - timer interrupt experiment
猜你喜欢
![[PaddleSeg源码阅读] 关于PaddleSeg模型返回的都是list这件小事](/img/a4/bc61237e6557762487783f21602973.png)
[PaddleSeg源码阅读] 关于PaddleSeg模型返回的都是list这件小事

Error :Could not decode ...With “UTF-8“-encoding. Editing not possible

Pytorch构建网络细节总结

腾讯四面面经,问傻了

【C#】正序、逆序、最大值、最小值和平均值

【C语言进阶】⑨动态内存分配知识总结 超详细

【Ucos-III源码分析】——事件标志组

Leetcode 47. 全排列 II

Image xmage de Huawei: Cherchez toutes les images du monde et voyez enfin Bodhisattva

深圳某游戏研发公司给每个工位都装监控,网友:堪比坐牢!
随机推荐
业务类库中的老门店类封装和调用
MySQL笔记: B站宋红康最新教程(持续更新中)
Leetcode45. 跳跃游戏 II
MySQL super detailed installation tutorial will teach you to install Mysql to use the simplest MySQL installation method of MySQL. This method is also simple to install and uninstall
鸿湖万联致远开发板正式合入OpenHarmony主干
Image xmage de Huawei: Cherchez toutes les images du monde et voyez enfin Bodhisattva
【Ucos-III源码分析】——任务创建
excel从右边查找字符并截取
腾讯四面面经,问傻了
STL string
要做的事情
让我们自定义反射系统
HALCON联合C#检测表面缺陷——ROI交互(三)(和图片同步缩放裁剪等功能)
S7-200smart case analysis - motion control programming (II)
golang中的读写锁原理
MySQL MySQL8其它新特性
MySQL超详细安装教程 手把手教你安装MySQL到使用MySQL 最简单的MySQL安装方式,这种方式装,卸载也简单
Anaconda 的认识以及和它相关的一些编辑器的简单介绍
Leetcode 47. 全排列 II
Bean的生命周期详解