C++基础--函数模板
函数模板是通用的函数描述,其使用泛型来定义函数。其实就是有些操作,如果撇开具体的变量的数据类型,其操作是一样的如果我们将这些操作写成一个模板,在调用不同变量的时候就设定好变量类型就可了,后续的操作基本都是一个流程了。
比如我要对两个变量进行交换,那么不管是int型、double型还是long型或者类或者结构体啥的,我都可以这样实现:
T A = AAAAA;
T B = SB;
T temp = A;
A = B;
B = tem;
这里的T就是数据类型的,不管是什么数据类型,只要可以进行如上操作的,都可以用这个模板来做。
1、函数模板定义
函数模板的定义基本上固定的:
template <typename T>
void aiZuoNiNa(T a)
{
}
其中,template是函数模板的关键字,关键字typename是声明该函数模板的泛型类型,可以用class来替代(C++98前没有typename,所以用class),这两个关键字和尖括号是必须的,typename之后的T可以任意写,只要符合C++命名规则即可,很多人会写做T。
需要注意的是,在定义函数模板的时候是不会创建任何函数的,只是在告诉编译器在调用模板函数的时候该如何定义函数并调用,也就是说如果定义了模板函数,但是从未调用过的话,是不会生成相应的函数的,在程序中使用了定义好的函数模板,那么编译器将检查使用的参数类型,然后根据类型来生成相应函数(就如同我们手写了一个函数一样)。所以即使定义函数模板只有一份,如果调用了两次且数据变量不同的话,编译器会生成两份独立的函数在可执行程序中,也就是说函数模板不会缩短可执行程序,最终的可执行程序也不会包含函数模板,但是会包含调用两次函数模板后编译器所生成的两个独立的函数。
函数模板一般是放在头文件中的。
并不是模板函数的所有参数都得是泛型,可以不要泛型,或者包含其它类型:
template <typename T>
void aiZuoNiNa(T a)
{
}
template <typename T>
void aiZuoNiNa(T a, int b)
{
}
template <typename T>
void aiZuoNiNa()
{
}
2、模板重载
上面一个例子涉及到函数模板的重载,函数模板的重载与普通函数重载一样,重载函数模板的时候,需要满足函数名相同、参数列表不同函数重载特点即可。
3、函数模板的局限性
这个要怎么说呢,应该说是某些情况不适合简单抽象化或者简单模板化,才导致了函数模板的局限性,比如比较两个变量的大小,对于int、float等数据类型可以实现模板化,但是如果是一个结构体或者一个类、或者一个数组等,在不重载比较操作符号(<、>、==)的时候显然不能这样比较吧。
4、显式具体化
因为有些情况可能不能直接简单的用函数模板,所以才会提供一个具体化函数定义(称为显式具体化,explicit specialization),其中包含所需要的代码,在编译器找到与调用函数匹配的具体化定义后就不再寻找模板函数了。也就是显示具体化函数优先级大于函数模板。C++98的具体化方法规定:
1、对于给定的函数名,可以有非模板函数、模板函数、显示具体化模板函数以及它们的重载;
2、显式具体化的原型和定义应以template<>开头,并通过名称来指定类型;
3、具体化优先于常规模板,而非模板函数优先于具体化和常规模板。
第一条有重载的意味,第二条指出显示具体化的格式,第三条指出当存在多个函数的时候,编译器寻找顺序是非模板函数>具体化模板函数>模板函数。在调用模板函数指定数据类型的时候编译器是会生成一个对应的函数实例,这个函数是不在代码中可见的,故而这种实例化是隐式的,而显示具体化则是在代码里定义的:
// 函数模板
template <typename T>
void jiaoJiRen(T a, T b)
{
}
//显式具体化
template<> void jiaoJiRen<char>(char a, char b)
{
}
5、实例化和具体化
一开始是只有隐式实例化,显示实例化是现在的C++才有的,显式实例化需要声明所需的数据类型(用<>指示数据类型),并在声明前面添加关键字template:
template void jiaoJiRen(int a, int b);
显式具体化是要求编译器在调用的时候不要按照函数模板中的方式来生成函数定义,而要用显式具体化的函数:
//方式一
template<> void jiaoJiRen<char>(char a, char b)
{
}
//方式二
template<> void jiaoJiRen(char a, char b)
{
}
显式具体化和显式实例化的区别:
1、具体化函数声明前
2、显式具体化除了声明还有函数定义,显式实例化只需要做函数声明即可。
3、在同个文件(或者转换单元)中使用同一种类型的显示实例化和显式具体化会出错。
函数模板这一块大致就记录这一些,我觉得暂时够用即可,毕竟是一个工具,目前就是挖的很深,没有使用的余地的话,很快就遗忘,个人的一点感受,之前看设计模式的时候觉得都记住了,一段时间后都模糊了,然后自己昨天写完一个小软件的时候才意识到自己其实用到了单例模式,再去查下单例模式,才知道我用的这个叫懒汉方式。所以有点感想,对于工具的一种学习方法是在实践中使用它,故而有句很装逼的话:
无他,但手熟尔。
C++基础--函数模板的更多相关文章
- C++进阶-1-模板基础(函数模板、类模板)
C++进阶 模板 1.1 函数模板 1 #include<iostream> 2 using namespace std; 3 4 // 模板 5 6 // 模板的简单实例 7 // 要求 ...
- Template 基础篇-函数模板(待看
Template 基础篇-函数模板 Template所代表的泛型编程是C++语言中的重要的组成部分,我将通过几篇blog对这半年以来的学习做一个系统的总结,本文是基础篇的第一部分. Template ...
- C++ 函数模板基础知识
为什么要引入模板:为了避免代码重复,程序员可以编写脱离数据类型通用模板. 模板的分类:函数模板 + 类模板 注意:模板的声明或定义只能在全局,命名空间或类范围内进行.不能在函数内进行,比如不能在mai ...
- [C++基础]那些容易被混淆的概念:函数/数组指针-指针函数/数组,类/函数模板-模板类/函数
函数指针-指针函数 函数指针的重点是指针.表示的是一个指针,它指向的是一个函数.eg: int (*pf)(); 指针函数的重点是函数.表示的是一个函数,它的返回值是指针.eg: int* fun() ...
- 【C++编程基础】(1)—— 函数原型声明、函数模板、引用、const 常引用、const 常量指针
一.函数原型声明: 1.函数声明告诉编译器函数的名称,和如何调用函数(返回类型和参数):函数定义提供了函数的实际主体. 2.强制性的:在C++中,如果函数调用的位置在函数定义之前,则要求在函数调用之前 ...
- 读书笔记_Effective_C++_条款四十五:运用成员函数模板接受所有兼容类型
比如有一个Base类和一个Derived类,像下面这样: class BaseClass {…}; class DerivedClass : public BaseClass {…}; 因为是父类与子 ...
- [Reprint] C++函数模板与类模板实例解析
这篇文章主要介绍了C++函数模板与类模板,需要的朋友可以参考下 本文针对C++函数模板与类模板进行了较为详尽的实例解析,有助于帮助读者加深对C++函数模板与类模板的理解.具体内容如下: 泛型编程( ...
- c++函数模板---3
原创博客:转载请标明出处:http://www.cnblogs.com/zxouxuewei/ 模板从大体上,可以分为两种:函数模板和类模板.函数模板是算法库的基础,类模板是建立标准库容器和迭代器的基 ...
- C++_进阶之函数模板_类模板
C++_进阶之函数模板_类模板 第一部分 前言 c++提供了函数模板(function template.)所谓函数模板,实际上是建立一个通用函数,其函数类型和形参类型不具体制定,用一个虚拟的类型来 ...
随机推荐
- 前端学习笔记系列一:2 Vue的单文件组件
(1)非单文件vue组件和单文件vue组件的一般写法 一个完整的vue组件会包括三个部分:一是template模板部分,二是js程序逻辑部分,三是css样式部分.每个组件都有属于自己的模板,js和样式 ...
- Redis集合类型
集合是元素无序且唯一的列表 命令 增加元素 SADD key member [member ...] > SADD letters a (integer) 1 > SADD letters ...
- 学习:java原理—反射机制
一.什么是反射:反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力.这一概念的提 出很快引发了计算机科学领域关于应用反射性的研究.它首先被程 ...
- 使用vim编译.cpp文件
一.编写代码 1.打开命令行终端,输入vim test.cpp,新建了一个文件叫做“test.cpp”:如果以前已经建立过这个文件,则是打开这个名字的文件. 2.按回车进入编辑界面,输入i进入编辑模式 ...
- esxi 版本升级命令
先把zip文件通过XShell或者WinSCP上传到esxi服务器上面去,然后执行以下命令,完成升级并重启就可以了.
- 使用Python的PIL库做的图像相似度对比源码备份
#!/usr/bin/python # Filename: histsimilar.py # -*- coding: utf-8 -*- import PIL.Image def make_regal ...
- 三、深入Vue组件——Vue插槽slot、动态组件
一.插槽slot() 1.1简单插槽slot [功能]用于从父组件中,通过子组件写成双标签,向子组件中放入自定的内容 parent.vue [1]首先把child写成双标签样式,把要插入的内容放双标签 ...
- H5页面,华为手机打开不加载JS的问题
今天在做H5页面放在其他手机上面都可以刷出列表,但是就是放在华为手机上面刷不出来,怎么想都想不通,后面主管说华为手机的浏览器是严格遵守H5什么鬼东西的,然后其他浏览器做到比较好的,如果有报错就帮我们解 ...
- Linux学习《第四章脚本》20200222
- NAND厂商哭晕:减产也阻止不了跌价
导读 NAND闪存价格已经连跌了6个季度,这让上游NAND厂商三星.东芝.美光等损失惨重,纷纷削减NAND产能.在群联台北电脑展上,群联公司董事长潘建成也预测NAND闪存价格已经跌破了成本,未来跌幅会 ...