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

目录

一、函数模板

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

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

3、函数模板的实现原理

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

二、类模板

1、类模板格式

2、使用类模板创建对象

3、类外定义成员函数

三、模板特化

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

2、模板全特化的实现

3、模板偏特化的实现


一、函数模板

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

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

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

所以我们引入了函数模板

         函数模板、类模板(含模板特化)_第1张图片函数模板、类模板(含模板特化)_第2张图片

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

(1) 定义

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

格式如下

template              // template
返回值类型 函数名(形参列表)
{
    //函数体
}


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

(2) 使用

使用的方式有两种

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

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

函数模板、类模板(含模板特化)_第3张图片

3、函数模板的实现原理

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

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

函数模板、类模板(含模板特化)_第4张图片

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

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

函数模板、类模板(含模板特化)_第5张图片

函数模板、类模板(含模板特化)_第6张图片

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

下面这种情况是允许的

函数模板、类模板(含模板特化)_第7张图片

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

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

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

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

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

二、类模板

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

1、类模板格式

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

2、使用类模板创建对象

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

函数模板、类模板(含模板特化)_第8张图片

3、类外定义成员函数

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

函数模板、类模板(含模板特化)_第9张图片

三、模板特化

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

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

函数模板、类模板(含模板特化)_第10张图片

函数模板、类模板(含模板特化)_第11张图片

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

2、模板全特化的实现

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

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

原本的函数模板:

函数模板、类模板(含模板特化)_第12张图片

特化以后的函数模板: 

函数模板、类模板(含模板特化)_第13张图片

3、模板偏特化的实现

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

函数原版如下

函数模板、类模板(含模板特化)_第14张图片

 模板偏特化如下

函数模板、类模板(含模板特化)_第15张图片

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

// 模板
template
struct Hash
{}

// 模板特化
template<>
struct Hash
{}

你可能感兴趣的:(C/C++,c++)