模板的进阶

思维导图:

目录

一. 类型模板参数

1. 类型模板参数了解

类型模板参数指的是:参数类型名称出现在模板参数列表里面,并且是在class 或者是 typename

关键字之后。

2. 类型模板参数的使用

2.1 class 与  typename 的区别

 一般情况下,默认使用 class 和 typename 没有什么本质区别

但是当我们在一个类里面再进行定义一个类的时候,当我们使用这个内嵌类型的时候就不能使用

class 关键字来定义参数模板了,此时需要使用typename 关键字。只单纯进行文字性输出,可能

不是很好理解,结合具体使用的场景,或许理解起来更容易。

(其实这个问题在对list 迭代器模拟实现的时候,就已经显现出来了),list 的迭代器本质是对指针

进行了封装以及相关运算符的重载。

类外定义一个函数,此函数可以实现对list 容器内数据的遍历。

 发现此时编译报错:

 分析:

因为此时list<T> 在编译的时候是一个没有进行实例化的类模板;编译器就无不知

道 list<T>::const_iterator 这是一个静态成员还是一个内嵌类型

解决:

此时的使用 typename 关键字,告知编译器这是一个内嵌类型,实例化的时候直接去类里面查找即

可。

二. 非类型模板参数

1. 非类型模板参数了解

类模板或函数模板的参数中有一个常量,可以把该参数当成一个常量来使用。

与类型模板参数的区分就是前面没有class 或者是typename 

2. 非类型模板参数的使用

 做个小测验:

 

 分析:

 

 1)非类型模板参数类型不能是浮点数,类对象,字符串。

2)  在编译的时候,非类型参数必须有一个确切的数值

三. 模板特化

在原有模板的基础上,限制模板参数的类型(也就是指定模板参数为特定的类型)

 问题的导入:

写一个模板函数:比较2个数据大小

我们发现此时这个模板函数不能很好 的解决问题,这时候可以借助函数模板特化进行处理 

1.函数模板特化

特化的步骤:

 

2. 类模板的特化
2.1 全特化

类模板全特化把所有的模板参数指定为具体的类型

2.2 偏特化

类模板偏特化把部分模板参数指定为具体的类型

偏特化:

1)必须先有一个原类的模板

2) 进行模板参数类型 的指定

// 原模板
template<class T1, class T2>
class Data
{
public:
	Data() { cout << "Data<T1, T2>" << endl; }
private:
	T1 _d1;
	T2 _d2;
};

// 偏特化同时也是对模板参数进行限制
template <typename T1, typename T2>
class Data <T1*, T2*>
{
public:
	Data() { cout << "Data<T1*, T2*>" << endl; }

private:
	T1 _d1;
	T2 _d2;
};

四.模板分离编译

1. 分离编译

一个工程由若干个源文件组成每一个源文件都需要经过单独的编译,链接生成对应的目标文件,

最终把所有生成的目标文件一起进行链接,形成可执行程序。

2. 模板的分离编译

模板的声明和定义分别在不同的文件里面。

当出现进行链接的时候,出现链接错误

 分析:

一个程序的运行需要经过:预编译,编译,汇编,链接。(对于这4个过程还需要在细分,感兴趣

的友友们,可以看一下,前期的博客)

程序执行的环境和预处理

 不知道各位是否有这样的疑惑:为什么 Func()不会出现链接的错误???

当对list .h  文件的内容进行汇编的时候,是可以生成对应 函数地址的,因此Func() 这个函数返回

类型,以及参数的具体情况是已知的,所有就可以进行函数栈帧的创建,就会生成对应的函数地址

3. 模板分离编译的解决
3.1 进行实例化

 但是当我们实参类型是double ,char ,short的时候,就会再次出现同样的问题,需要我们一一

指定实例化,这并不是“一劳永逸”的方法

3.2 模板声明和定义在同一个文件里面

 此时就不会出现链接错误:因为当对test.cpp 文件里面的内容进行汇编生成指令的时候,模板的声

明和定义都有,此时函数模板已经被实例化具体的函数了,有对应的地址。

 4. 模板“复盘”
模板优点

1)可以复用

2)增强代码的灵活性(“适配性”)

模板缺点

1)代码“膨胀”,增加了编译的时间

2)编译报错的时候,错误信息不精确,定位不准确

  • 60
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 27
    评论
评论 27
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值