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.)所谓函数模板,实际上是建立一个通用函数,其函数类型和形参类型不具体制定,用一个虚拟的类型来 ...
随机推荐
- Mybatis入门(六)联查之多对一
Mysql可以联查,但Mybatis也可以联查只是没有MySQL联查的舒服需要配置很多文件. 开始搭建环境: MySQL新建两个表一个Student一个Teacher表: Teacher表: CREA ...
- CentOS 下 安装 nginx 执行配置命令 ./configure 报错
CentOS 下 安装 nginx 执行配置命令 ./configure --prefix=/opt/nginx --sbin-path=/usr/bin/nginx 时提示以下错误: checkin ...
- P1076 Wifi密码
P1076 Wifi密码 转跳点:
- 有没有比NRF51822更好的智能穿戴蓝牙方案
现在在智能穿戴领域市场不断的追求低功耗.低成本的蓝牙芯片.蓝牙芯片目前除了Dialog公司研制蓝牙芯片是最求超低功耗的但是对于其它性能上还比较满足不了其它领域的功能,另外NORDIC.TI的蓝牙芯片虽 ...
- f_lseek
我在STM32中移植了fatfs文件系统,实现在SD卡对文件的读写.在普通读写中都没有问题,但是一旦我关闭文件系统,再次打开读写,之前写的数据就被覆盖.比如举个例子: u8 tx_buff ...
- 基于 若依 ,或者使用 LayUi ,用来展示数据表,同时要 转换字典数据时的转换的建议
原作者在做这个项目时,他把所有数据字典都放在数据库表中了,这种方法的确比较好,适用于中大型项目,方便统一管理字典:而且优点突出,字典值变化后不需要调整前端代码: 但是在实际开发项目中,一些小型的项目, ...
- 012.CI4框架CodeIgniter, 加载并调用自己的Libraries库
01. 在Libraries目录创建一个Mylib文件,内容是一个简单的类 <?php namespace App\Controllers; class Home extends BaseCon ...
- JS:递归基础及范例——斐波那契数列 、 杨辉三角
定义:程序调用自身的编程技巧称为递归.一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就 ...
- Codeforces 459E Roland and Rose
本以为是个树形DP,按照树形DP的方法在那里dfs,结果WA到死,因为它存在有向环,不是树,凡是存在环的情况切记不要用树形的方法去做 题目的突破点在于将边排完序之后,用点表示以该点为边结尾的最大长度, ...
- 埃及分数问题 迭代加深搜索/IDA*
输入整数a,b (0<a<b<500) ,输出最佳表达式 使得加数个数尽量小,如果加数个数相同,则最小的分数越大越好 ,输出表达式 考虑从小到大枚举深度上限maxd,每次执行只考虑深 ...