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

目录

一、函数模板

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>
{}
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++ 函数模板特化是指为特定的数据类型或者特定的函数参数提供特殊的实现。这样可以在处理某些特殊情况时,使用不同的实现逻辑,以满足特定的需求。 函数模板特化的语法如下: ```cpp template <> return_type function_name<specific_type>(parameters) { // 实现特化的代码 } ``` 其中,`template <>` 表示这是一个函数模板特化版本,`specific_type` 是要特化的数据类型,`function_name` 是要特化函数名,`parameters` 是函数的参数列表,`return_type` 是函数的返回类型。 举个例子,设我们有一个通用的函数模板用于计算两个数相加: ```cpp template <typename T> T add(T a, T b) { return a + b; } ``` 如果我们想要为 `int` 类型提供一个特化版本,实现乘法运算而不是加法运算,可以这样写: ```cpp template <> int add<int>(int a, int b) { return a * b; } ``` 这样,在使用 `add` 函数模板时,如果参数是 `int` 类型,就会自动选择特化版本进行计算。 需要注意的是,函数模板特化是根据数据类型进行匹配的,而不是根据参数数量或者参数类型进行匹配。因此,在进行函数模板特化时,要确保特化版本与通用版本的参数类型和数量完一致,否则可能会导致编译错误。 另外,还可以进行部分特化,即只特化其中一部分参数类型。部分特化的语法与完特化类似,只是在模板参数列表中指定部分参数类型即可。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值