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

语法:

1.template<typename T
2.函数的声明或定义

解释:
template:声明创建模板
typename:表明其后面的符号是一种数据类型,可以用class代替
T:通用的数据类型,名称可以替换,通常为大写字母

示例

#include<iostream>
using namespace std;
//交换两个整型数
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;
}
void test()
{int a=10;int b=20;swapint(a,b);cout<<"a="<<a<<endl;cout<<"b="<<b<<endl;double c=1.1;double d=2.2;swapdouble(c,d);cout<<"c="<<c<<endl;cout<<"d="<<d<<endl;
}
int main()
{test();
}

但是我们会发现数据类型有很多,除了int double这些 还有用户自己定义的struct类型,所以会有无数个。为了解决这个问题,用模板来解决。

代码如下:

//函数模板
template<typename T>//typename可换为class
void myswap(T &a,T &b)
{T temp=a;a=b;b=temp;
}

有两种方式使用模板
(1).自动类型推导
直接让编译器自己判断数据类型,再做运算

#include<iostream>
using namespace std;
template<typename T>//typename可换为class
void myswap(T &a,T &b)
{T temp=a;a=b;b=temp;
}
void test()
{int a=10;int b=20;myswap(a,b);cout<<"a="<<a<<endl;cout<<"b="<<b<<endl;double c=1.1;double d=2.2;myswap(c,d);cout<<"c="<<c<<endl;cout<<"d="<<d<<endl;
}
int main()
{test();
}

(2).显示指定类型
直接在编译时告诉编译器指定的类型

#include<iostream>
using namespace std;
template<typename T>//typename可换为class
void myswap(T &a,T &b)
{T temp=a;a=b;b=temp;
}
void test()
{int a=10;int b=20;myswap<int>(a,b);cout<<"a="<<a<<endl;cout<<"b="<<b<<endl;double c=1.1;double d=2.2;myswap<double>(c,d);cout<<"c="<<c<<endl;cout<<"d="<<d<<endl;
}
int main()
{test();
}

———————————————————————————————————————

2.函数模板注意事项
注意事项:
(1)自动类型推导,必须推导出一致的数据类型T,才可以使用
(2)模板必须要确定出T的数据类型,才可以使用
(1)如:
在前文的test函数中:

void test()
{int a=10;char c='c';myswap(a,c)//错误
}

(2)如:

template<class T>
void func()
{cout<<"hello"<<endl;
}
void test()
{func();
}
int main()
{test();
}

此程序是无法运行的,因为模板没有确定T的数据类型
如果一定要输出,则一定要在调用模板函数时显示数据类型
代码如下:

template<class T>
void func()
{cout<<"hello"<<endl;
}
void test()
{func<int>();//显示数据类型
}
int main()
{test();
}

———————————————————————————————————————

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

#include<iostream>
using namespace std;
template<class T>
void myswap(T &a,T &b)
{T temp=a;a=b;b=temp;
}
//排序算法
template<class T>
void mysort(T arr[],int len)
{int i,j;for(i=0;i<len-1;i++){int max=i;for(j=i+1;j<len;j++){if(arr[max]<arr[j]){max=j;//更新最大值下标}}if(max!=j){//交换max和i下标元素myswap(arr[max],arr[i]);}}
}
//提供一个打印数组的模板
template<class T>
void print(T arr[],int len)
{for(int i=0;i<len;i++)cout<<arr[i]<<" ";cout<<endl;
}
void test1()
{char charArr[]="badcfe";int num=sizeof(charArr)/sizeof(char);mysort(charArr,num);print(charArr,num);
}
void test2()
{int intArr[]={7,5,1,3,9,2,4,6,8};int num=sizeof(intArr)/sizeof(int);mysort(intArr,num);print(intArr,num);
}
int main()
{test1();test2();
}

———————————————————————————————————————

4.普通模板和函数模板的区别
普通函数调用时可以发生自动类型转换
函数模板调用时,如果利用自动类型推导,不会发生隐式类型转换
如果利用显示指定类型的方式,可以发生隐式类型转换

这里不做说明

———————————————————————————————————————

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

1.直接上代码

#include<iostream>
using namespace std;
void myprint(int a,int b)
{cout<<"调用的普通函数"<<endl;
}
template<class T>
void myprint(T a,T b)
{cout<<"调用的模板"<<endl;
}
void test()
{int a=10;int b=20;myprint(a,b);
}
int main()
{test();
}

运行结果如下:

上面的例子可以轻松看出一点问题,假如普通函数的语句为myprint(int a,int b);打上分号后 该语句会使得报错,那么这时应该要想到用上函数模板

2.可以通过空模板参数列表 强制调用 函数模板

代码如下:

#include<iostream>
using namespace std;
void myprint(int a,int b);
template<class T>
void myprint(T a,T b)
{cout<<"调用的模板"<<endl;
}
void test()
{int a=10;int b=20;//通过空模板参数列表,强制调用函数模板myprint<>(a,b);
}
int main()
{test();
}

运行结果如下:

3.函数模板也可以发生重载,这点不做程序上的说明,注意下重载的时函数名,里面的变量类型不一定会相同,因此函数调用时会调用变量类型和数量相同的模板函数。

那么第4点所说的“如果函数模板可以产生更好的匹配,优先调用函数模板”是什么意思呢?
上代码:

#include<iostream>
using namespace std;
void myprint(int a,int b)
{cout<<"调用的普通函数"<<endl;
}
template<class T>
void myprint(T a,T b)
{cout<<"调用的模板"<<endl;
}
void test()
{char c1='a';char c2='b';myprint(c1,c2);
}
int main()
{test();
}

运行结果如下:

那么为什么会有这样的结果呢?
那是因为在调用普通函数时,编译器会自动把char类型转化为int类型再做交换,但是相比之下,模板函数则不需要做此变换,编译器会自动选择更简单的模板函数的方式调用该函数。

——————————————————————————————————————

6.模板的局限性
例如:

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

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

再例如:

template
void f(T a,T b)
{
if(a>b){…}
}

在上述代码中,如果T的数据类型传入的是像Person这样的自定义数据类型,也无法正常运行

因此C++为了解决这种问题,提供模板的重载,可以为这些特定的类型提供具体化的模板

解决方法:
在程序中利用具体化Person的版本实现代码,具体化优先调用
template<>返回值类型 函数名(Person &a,Person &b)
{//写出执行的方式
}

函数模板---清晰的例子,通俗易懂(超详细)相关推荐

  1. c语言指针用法及实际应用详解,通俗易懂超详细

    c语言指针用法及实际应用详解,通俗易懂超详细! \\\插播一条:文章末尾有惊喜哟~/// 今天给大家来讲解一下指针. 我会由浅到深,最后联合实际应用讲解,让大家学会指针的同时,知道大佬们都用指针来干嘛 ...

  2. c语言指针用法及实际应用详解,通俗易懂超详细!

    大家好,我是无际. 今天给大家来讲解一下指针. 我会由浅到深,最后结合实际应用讲解,让大家学会指针的同时,知道大佬们都用指针来干嘛! 长文预警!全文大约5200多字,学指针看这篇文章就够了! 很多人跟 ...

  3. Eclipse 注释模板的说明及设置(超详细)

    1.在哪里里设置注解模板 设置注释模板的位置 ①.找到工作菜单 在这里插入图片描述 ②.依次点进Window --> Preference --> Java->Code Style ...

  4. 计算机二级lookup函数,lookup函数的使用方法,步骤超详细(动态图文讲解)

    Excel中最常用的查找引用函数当之无愧的是Vlookup,但是有一个函数比Vlookup函数的功能更强大,此函数就是Lookup.今天IT考试网就借助it考试平台为大家分享lookup函数的使用方法 ...

  5. java中io流案例_Java IO流的简单使用 通俗易懂 超详细 【内含案例】

    IO流简单使用 输入和输出是相对于程序来说的,读取到程序中叫做输入,写到文件中叫输出. InputStream 字节输入流 InputStream 字节输入流基类,是字节输入流所有类的超类 // 从输 ...

  6. java security 详解_Spring Security入门教程 通俗易懂 超详细 【内含案例】

    Spring Security的简单使用 简介 SSM 整合 Security 是比较麻烦的,虽然Security的功能比 Shiro 强大,相反却没有Shiro的使用量多 SpringBoot出现后 ...

  7. java单例模式实例_Java设计模式之单例模式 通俗易懂 超详细 【内含案例】

    单例模式 什么是单例模式 ? 确保程序中一个类只能被实例化一次,实现这种功能就叫单例模式 单例模式的好处是什么 ? 方便控制对象 节省资源减少浪费 怎么实现单例模式 ? 构造私有化 调用静态方法返回实 ...

  8. 简述类模板函数模板template (typename T)

    相信很多刚入门c++的同学在学数据结构或者查看大佬的代码中,我们都会看到: template <typename T> 类模板; template<typename T> cl ...

  9. Docker02 狂神Docker视频学习笔记 :【狂神说Java 哔哩哔哩】Docker最新超详细版教程通俗易懂

    目录 0. 视频源 0. 学习网址 基础篇 1. Docker概述 1.1 Docker为什么出现? 1.2 Docker历史 1.3 Docker能干什么 2. Docker安装 2.1 Docke ...

  10. 超详细图解!【MySQL进阶篇】存储过程,视图,索引,函数,触发器

    超详细图解![MySQL进阶篇]存储过程,视图,索引,函数,触发器 1.1 下载Linux 安装包 1.2 安装MySQL 1.3 启动 MySQL 服务 1.4 登录MySQL 2\. 索引 2.1 ...

最新文章

  1. 网络协议——TCP/IP协议
  2. 使用存储过程将文本导入数据库表
  3. java8 java9 接口 interface
  4. 服务器经常崩溃??让我们来看看简单的内存知识:C语言——内存管理
  5. 4.1 选择IDC机房 4.2 硬件服务器选型 4.3 上架服务器 4.4/4.5 装系统
  6. linux源代码剖析之include-asm
  7. 【渝粤教育】国家开放大学2018年秋季 0692-21T化工设备机械基础 参考试题
  8. 《Python密码学编程》——2.6 本书的文本换行
  9. jmeter压力测试+badboy脚本录制
  10. 江苏事业单位计算机类考试题型,江苏事业单位统考各岗位考试类型和题目分值一览!...
  11. 低阶的Newton-Cotes求积公式 | 梯形求积公式、Simpson求积公式、Cotes求积公式
  12. 43.于电脑右下角的小喇叭不见了的解决
  13. 网站seo优化到底该怎么做?
  14. 知到网课中国戏曲剧种鉴赏考试试题|真题演练|题库(含答案)
  15. 倒水c语言,洛谷 P1432 倒水问题
  16. 漏洞优先级技术(VPT)导论
  17. r计算百分位数_R中产生的分位数和百分位数之间的差异
  18. 扫描仪软件测试自学,资讯详情-静态代码扫描工具 - sonarQube-柠檬班-自动化测试-软件测试培训-自学官网...
  19. 银联扫码支付及静态码回调验签
  20. mac地址储存在计算机的内存,mac地址通常存在计算机的

热门文章

  1. awk的关联数组版本支持
  2. 用 WebSocket 实现一个简单的客服聊天系统
  3. android 中使用svg
  4. Android面试问题收集总结
  5. 【转】如何调试bash脚本
  6. [置顶]       webservice系列1---基于web工程上写一个基本数据类型的webservice
  7. 开机时提示F1continue, F2 setup
  8. sever2008 ad用户和计算机不见,windows-server-2008 – 当我使用Powershell将用户添加到安全组时,它们不会显示在AD中...
  9. php有的图片显示不出来,图片显示不出来,但是数据库里有显示
  10. js数组再倒数第二个添加元素_js 循环对象数组将元素逐个添加至新数组问题