C++?模板(进阶)!!!

一、引言

在之前我们已经介绍过C++中引入的非常好用的一个工具--模板,同时借助模拟实现string、vector、list等容器熟悉了如何使用模板,今天我们将要一起学习有关模板的进阶知识,如果还想了解模板的概念以及基础的使用可以跳转到以下链接:

C++?模板!!!_template vector & vector ::func(co-CSDN博客 https://blog.csdn.net/2501_90507065/article/details/147571025?spm=1001.2014.3001.5501

二、非类型模板参数

1、引入

在平常的使用情景中,我们会遇到类似在类中定义静态数组的情况,这时候就会存在静态定义数组最常见的问题:空间开少了不够用,开多了用不完。这时候我们常会用'#define'来解决,但是这种处理方法也只是治标不治本,仍然是写死的,不能让用户很好的控制数组空间的大小,该怎么办呢?这时候就可以使用我们接下来要提到的非类型模板参数

2、什么是非类型模板参数?

我们常用的模板参数一般都是类型形参,跟在class或者typename之后,这样可以很好的解决由于类型不同但内容相同的类需要写很多份的问题;而非类型模板参数就是用一个常量作为类(函数)模板的参数,在模板中可以将这个参数当成常量来使用,借助它我们就可以解决上面的问题:

复制代码
#include <iostream>
using namespace std;
template<class T , int N>
class A
{
private:
	T arr[N];
};
void test1()
{
	A<int, 10> a;
}
int main()
{
	test1();

	return 0;
}

三、函数模板的特化

1、引入

当完成一个函数模板时,我们有时候并不是期望当传入所有参数类型时都进行相同的操作,比如:当一个用于比较的函数,当传入指针类型时我们可能更希望对它们解引用之后的内容进行比较,这时候我们就需要对该函数进行特化了

2、函数模板的特化

我们解决上面的问题,我们引入了函数模板的特化,语法如下:

复制代码
//template<>//为了说明这是一个函数模板
//返回值需要与对应的函数模板相同   //函数名<预计传入的类型> //参数列表
//函数体

在函数模板的特化时,我们需要注意以下几个点:

(1). 必须要先有一个基础的函数模板

(2). 关键字template后面接一对空的尖括号<>

(3). 函数名后跟一对尖括号,尖括号中指定需要特化的类型

(4). 函数形参表: 必须要和模板函数的基础参数类型完全相同,如果不同编译器可能会报一些奇怪的错误

下面的代码是一个实际的应用,解决在"引入"部分提出的问题:

复制代码
template<class T>
bool Less(T t1, T t2)
{
	return t1 < t2;
}
template<>
bool Less<int*>(int* t1, int* t2)
{
	return *t1 < *t2;
}

除了上面提到的函数模板特化之外,还支持了部分特化,所以上面的函数模板还支持这样定义:

复制代码
template<class T1,class T2>
bool Less(T1 t1, T2 t2)
{
	return t1 < t2;
}
template<class T1>
bool Less<T1,int*>(T1 t1, int* t2)
{
	return t1 < *t2;
}

这段代码的意思是:当第二个参数是int*类型时,就采取第二种比较方法,虽然一般不会有这样的情况出现,但是我们主要是为了说明这样一个语法点

四、类模板的特化

类模板的特化是为了解决类似函数模板特化想解决的问题的,同时类模板也分为全特化与偏特化,接下来我们一个一个的解释

1、全特化

全特化是指将类模板参数列表中所有的参数都进行特殊化处理,我们使用一个简单的日期类来进行演示:

复制代码
template<class T1,class T2>
class Date
{
public:
	//成员函数列表
private:
	T1 _d1;
	T2 _d2;
};
template<>
class Date<int, char>
{
public:
	//成员函数列表
private:
	int _d1;
	char _d2;
};

可以看出,类模板的特化与函数模板的特化是很相似的,我们仍然需要在类名之后对特化的参数进行写明

2、偏特化

(1).部分特化

部分特化是指将一部分的类模板参数进行特殊化处理:

复制代码
template<class T1>
class Date<T1, int>
{
public:
	//成员函数列表
private:
	T1 _d1;
	int _d2;
};
(2).对参数进行更进一步的限制

我们可以对于某些参数进行一些限制,达到特殊化处理模板参数的目的,下面是将参数特化为指针类型:

复制代码
template<class T1,class T2>
class Date<T1*, T2*>
{
public:
	//成员函数列表
private:
	T1 _d1;
	T2 _d2;
};

自然的,我们还可以将参数特化为引用类型,这里就不做演示了

五、结语

这就是本期有关模板进阶全部的内容了,期待各位于晏、亦菲与我一起交流、学习、进步!

相关推荐
乌鸦9447 分钟前
《STL--string的使用及其底层实现》
开发语言·c++·stl·string使用及其模拟实现
霖0010 分钟前
同步/异步电路;同步/异步复位
开发语言·前端·javascript·嵌入式硬件·fpga开发·信号处理
真智AI32 分钟前
如何用 Qwen1.5-7B-Chat 模型打造高效轻量的 Python 智能助手(详细实操指南)
开发语言·python
一只鱼^_32 分钟前
力扣第450场周赛
数据结构·c++·算法·leetcode·近邻算法·广度优先·图搜索算法
不知道写什么的作者37 分钟前
Python安全密码生成器:告别弱密码的最佳实践
开发语言·python
lyj16899741 分钟前
vite搭建vue3项目及相关配置
开发语言·javascript·ecmascript
嵌入式小能手1 小时前
Regmap子系统之六轴传感器驱动-完整驱动icm20607.c示例源码
c语言·开发语言
helloworld工程师1 小时前
CI/CD的演进之路
java·开发语言·ci/cd
汉卿HanQ1 小时前
技术篇-2.5.Matlab应用场景及开发工具安装
开发语言·数学建模·matlab
o0向阳而生0o1 小时前
50、js 中var { ipcRenderer } = require(‘electron‘);是什么意思?
开发语言·javascript·electron