100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > 函数模板 类模板(含模板特化)

函数模板 类模板(含模板特化)

时间:2020-06-16 12:12:20

相关推荐

函数模板 类模板(含模板特化)

目录

一、函数模板

1、为什么要使用函数模板?

2、函数模板的定义及其使用

3、函数模板的实现原理

4、特例:同名非模板函数能和同名模板函数 同时存在

二、类模板

1、类模板格式

2、使用类模板创建对象

3、类外定义成员函数

三、模板特化

1、为什么会有模板特化?

2、模板全特化的实现

3、模板偏特化的实现

一、函数模板

1、为什么要使用函数模板?

我们想实现两个数的交换,但是有的时候,数据类型是int,有的时候是float,实现的方法是一样的,只是数据类型的不同

每增加一种类型就要增加一个函数,未免过于麻烦

所以我们引入了函数模板

2、函数模板的定义及其使用

(1) 定义

函数模板根据给定的实参类型产生 函数的指定类型版本

格式如下

template<class T> // template<typename T>返回值类型 函数名(形参列表){//函数体}/*假设要定义一个交换两个数的函数模板*/template<class T> //声明使用函数模板,下面紧跟的函数就可以使用数据类型T了void Swap(T& x, T& y) //T 代表某种未知的数据类型,根据输入的实参决定{T tmp = x; x = y;y = tmp;}

(2) 使用

使用的方式有两种

第一种,隐式实例化—— 让编译器自己去推导实参类型。

第二种,显式实例化—— 自己显式指定传入的类型。如果传入的类型和指定类型不一致,会被强制转化为指定的类型,比如指定的是int类型,但传入的是double类型,那么double就会被强制转化成int

3、函数模板的实现原理

函数模板类似于一套模具,使用指定的模具能够创造出指定类型的饼干

在编译阶段,如果未指定类型,那么编译器就会根据传入的实参类型,产生一份对应的类型的函数

我们再通过反汇编来能够发现,每次实例化生成的函数都是不一样的!!

而且编译器会自动加上推导结果

4、特例:同名非模板函数能和同名模板函数 同时存在

下面这种情况是允许的

传入的参数是int类型时候,优先调用非模板函数

因为模板函数需要先实例化再调用,但是非模板函数能够直接调用,手边既然有工具为什么还要去商店里买呢??

int i1 = 10, i2 = 20;Swap(i1, i2);

但是如果传入的参数是double类型,由于没有合适的非模板函数,那么就只能调用模板实例化的函数

double d1 = 10.1, d2 = 10.2;Swap(d1, d2);

二、类模板

类模板和函数模板类似,不同之处在于类模板不会自动推导参数类型,只能显式指定

1、类模板格式

template<class T>class Person{public:void SetWeight(const T& w);private:T* weight;};

2、使用类模板创建对象

类模板没有指定类型的话,就会报错

3、类外定义成员函数

类内定义成员函数没有什么特别要注意的地方,但是类外定义就需要注意了

三、模板特化

1、为什么会有模板特化?

以两数之和相加为例,如果是两个int类型或者char类型的数相加,完全没有问题,因为C语言库已经重载了 运算符“+”的int版本和char版本,那如果是两个对象相加呢?这个时候就会出现问题,自定义类型相加需要自己重新实现运算符“+”的重载。

对于这种特殊情况,我们需要另外拎出来单独处理,这样的我们称之为“模板特化”(可以理解为特殊化处理)

2、模板全特化的实现

全特化:所有的虚拟类型都需要指定类型

关于模板特化,我们只需要将原版复制一份,拿来修改即可,模板特化以后的函数 和 原本的函数模板如下:

原本的函数模板:

特化以后的函数模板:

3、模板偏特化的实现

偏特化:只有部分虚拟类型需要指定类型

函数原版如下

模板偏特化如下

提醒:模板特化不仅仅可以用于函数模板,类模板(结构体模板)一样适用

// 模板template<class K>struct Hash{}// 模板特化template<>struct Hash<std::string>{}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。