C++ 模板进阶

21 篇文章 1 订阅
18 篇文章 0 订阅

这是在之前我写的模板博客c++ 类模版初阶-CSDN博客之后,进行的补充。主要是介绍非模板类型参数、模板的特化和模板不能写在两个文件里面的原因。

非模板类型参数

我们一般用到的类型都是template<class T>这种模板类型,并不代表某种具体的变量类型。但是我们也可以创造非模板类型:

例如我们要用模板来创造一个可以申请任意长度和类型的arry,其中长度它的类型一定是size_t,唯一不同的就是size_t对应的值。那么此时就可以用非模板类型参数:

注意:

1. 浮点数、类对象以及字符串是不允许作为非类型模板参数的。
2. 非类型的模板参数必须在编译期就能确认结果。

模板的特化

通常情况下,使用模板可以实现一些与类型无关的代码,但对于一些特殊类型的可能会得到一些
错误的结果,需要特殊处理,比如:实现了一个专门用来进行小于比较的函数模板

函数模板特化

但是如果我们遇到了某些特殊类:

date就不能直接被比较,除非类里面支持了相关的:

但是如果我们是调用它的指针进行比较呢,就只会比较他们的地址,所以要用到模板的特化

有特化后,程序就会优先走模板的特化。

函数模板的特化步骤:
1. 必须要先有一个基础的函数模板
2. 关键字template后面接一对空的尖括号<>
3. 函数名后跟一对尖括号,尖括号中指定需要特化的类型
4. 函数形参表: 必须要和模板函数的基础参数类型完全相同,如果不同编译器可能会报一些奇
怪的错误。

类模版特化

例如以下面的类模版进行举例:

全特化

将所有类型都指定的特化叫全特化

偏特化(半特化)

这种只要后面的参数是double就会走,除非有比它还全的全特化。例如我们的构造是double double那么就会走这个偏特化,如果是int double那么就会走上面的全特化。

半特化可以进一步限制参数类型:

我们不仅可以用模板的特化,还可以用普通函数进行重载来解决这类问题:

普通函数重载比模板的特化更简单,所以直接用普通函数重载就行了。

模板不能写在两个文件里面的原因

我们写一个项目的时候,必须把模板全部写在.h里面,原因是什么呢?

这里我们看到分离编写是会报编译错误的。

我们如果要知道原因是什么,首先就要大致了解一下编译链接相关的知识

我们的程序要经过编译链接等过形成计算机可以读懂的二进制文件,其中编译分为预编译(预处理)、编译。预编译是做宏处理,注释去除、把头文件的东西拷贝过来等操作,编译就是进行语法,词法,语义分析,然后变成汇编语言,中间再经过汇编变成二进制.o文件。然后就是链接,将所有的.o文件通过链接库链接成.exe文件。

这里我们将写有模板的文件叫做temp.cpp、temp.h,有主函数的是test.cpp

那么我们如果将模板分别写在temp.h和temp.cpp里面,就会导致在预编译的时候,temp.h里面的模板相关代码会全部拷贝到test.cpp文件里面,导致模板的代码分割到两块文件里面去了。且在编译的时候,我们的.cpp文件是独立进行编译的,而我们的模板又是按需实例化的,如果没有被调用就不会实例化出来,导致一个test.cpp里面调用了而找不到,但它不会报错,会信任在其他.cpp文件里面有相关的函数,在链接的时候去找。但另一个temp.cpp文件里面因为是独立编译收不到test.cpp里面的调用,所以就没有实例化。那么在链接的时候原本想要找对应实例化函数的就找不到,然后就报错了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值