C++初阶 | [十二] 模板进阶

news2025/2/25 21:42:25

摘要:非类型模板参数,类模板的特化,模板的分离编译,模板总结

前言:C++初阶终篇


1. 非类型模板参数

类型模板参数:如下代码,T 为模板的类型参数。 

#define N 10
template<class T>
class A
{
public:

private:
	T* _a[N];
};

void test_1()
{
	A<int> a1;
	A<double> a2;
}

非类型模板参数:对于上述代码,如果我们想要对于不同的数据类型创建不同大小的_a数组呢?例如,对于 A<int> 我们可能只要在其中存储10个 int 数据,而 A<double> 我们可能需要在其中存储 100 个 double 类型的数据。所以,对于这样的需求,我们可以在模板中加入非类型模板参数来满足。

template<class T, size_t N>
class A
{
public:

private:
	T* _a[N];
};

void test_1()
{
	A<int, 10> a1;
	A<double, 100> a2;
}

如上代码,其中的 size_t N 即为模板中的非类型模板参数
对于非类型模板参数有两个要求:(ps. char 也可以,char 也是属于整型家族。另外,C++98只支持整型,C++98之后支持非整型)

(补充) array

std::array
------------------------------------------
template<class T, size_t N> class array;

cplusplus.com/reference/array/array/

array 的意义: 

  • C语言:对于 int a[10];  a[15] = 1; 不会检查越界,a[15] 这个过程本质上是指针解引用
  • C++:对于 array<int ,10> a2; a2[15] = 1; 会检查越界,这里的 a2[15] 本质上是函数调用,所以可以在函数里进行执行越界检查。

C++11初衷是希望大家用这个来代替静态数组,但其实有更好的选择——vector。vector不仅对于越界设置了检查,而且可以按需求进行初始化(array不能按自己需求初始化)


2. 模板的特化

特化:针对某些类型做特殊处理

1)类模板的特化

  • 全特化 

e.g.

上图所展示的即为类模板的全特化,即针对 Data 类中 int 和 char 类型做特殊处理。

#include<iostream>

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

template<>
class Data<int, char>
{
public:
	Data()
	{
		std::cout << "Data<int, char>" << std::endl;
	}
private:
	int _d1;
	char _d2;
};


void test_2()
{
	Data<int, int> d1;
	Data<int, char> d2;
}

int main()
{
	//test_1();
	test_2();
	return 0;
}

执行上述代码的结果为:

Data<T1, T2>
Data<int, char>

全特化即是将模板参数列表中所有的参数都确定化。 

  • 偏特化

(也称半特化)

偏特化:任何针对模版参数进一步进行条件限制设计的特化版本。

(针对上述代码所写的 Data 类所举出的例子) 

  1. 方式一:将模板参数类表中的一部分参数特化。

    template<class T1 , class T2>
    class Data
    { …… };


    template<>
    class Data<T1,double>
    { …… };

     
  2. 方式二针对模板参数更进一步的条件限制

    template<class T1 , class T2>
    class Data
    { …… };


    template<>
    class Data<T1*,T2*>
    { …… }; //这里的意思是只要的类型为指针(例如:int* , double* , char* , ……)就调用这个特化出来的 class Data 

2)函数模板的特化 

引入:在 优先级队列 的文章中我们讨论了 对于 priority_queue<Date*> 如何通过仿函数来实现“自定义比较的规则”。这里,我们可以选择通过函数模板的特化来实现。即对 class Less 实现特化。

但是,对于上图所展示的代码,class Less 的成员函数的参数列表按上图的写法会发生传值拷贝,传值拷贝对于自定义类型可能会有深浅拷贝的问题。 因此,参数列表建议改成 cosnt 引用,然而,这同时会给函数模板特化带来一些小问题。

(如果你需要上图的代码↓) 

template<class T>
class Less
{
	bool operator()(const T& left, const T& right)
	{
		return left < right;
	}
};


template<>
class Less<Date*>
{
	bool operator()(Date* const& left, Date* const& right)
	{
		return *left < *right;
	}
};

 3)sum.

如果需要,类模板可以使用特化,而函数模板一般不使用特化,更好的选择是实现重载。相当于自己实例化出来一个针对某个数据类型的函数,而自己实例化的这个函数会与函数模板根据类型推导由编译器自动生成的实例化出来的函数构成重载。


3. 模板的分离编译

1)函数模板

2)类模板

类模板的分离编译一般是头文件声明成员(成员变量和成员函数),另外的 .cpp 文件中定义成员函数,以这样的形式分离。同样会产生如函数模板分离编译的链接错误。

3)sum.

如果声明和定义都在一个头文件里,那么预处理展开之后就相当于 调用定义 都在同一个文件里,编译的时候就可以通过调用语句“告诉”编译器通过模板的定义怎样实例化。

(ps.如果非得使模板的声明和定义分离,可以不声明的同时定义,但最好要把声明和定义放在一个文件里)


4. 模板总结

【优点】

1. 模板复用了代码,节省资源,更快的迭代开发,C++的标准模板库(STL)因此而产生;

2. 增强了代码的灵活性。

【缺陷】

1. 模板会导致代码膨胀问题,也会导致编译时间变长;

2. 出现模板编译错误时,错误信息非常凌乱,不易定位错误。


END

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1585618.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何理解单片机 pwm 控制的基本原理?

单片机PWM&#xff08;脉宽调制&#xff09;控制的基本原理&#xff0c;简而言之&#xff0c;就是通过改变脉冲信号的宽度&#xff08;占空比&#xff09;来控制模拟电路。这涉及到单片机生成一系列脉冲信号&#xff0c;每个脉冲信号的高电平持续时间和整个周期的比值&#xff…

4051A/B/C/D/E–S信号/频谱分析仪

4051A/B/C/D/E–S信号/频谱分析仪 频段26.5GHz 计数分辨率0.001Hz 同轴频率26.5GHz 4051-S系列信号/频谱分析仪可广泛应用于移动通信、汽车电子、物联网、半导体等领域的信号及设备测试。 PART.01 产品综述 —— 频率范围覆盖&#xff1a;9kHz~26.5GHz# 4051-S系列信号/频…

一起找bug之购物

如果不是购物车满了&#xff0c;大概都不会发现这个 bug 淘宝 APP 修复了购物车满的情况下&#xff0c;往里面添加新商品时&#xff0c;会把一个老商品移入收藏夹&#xff0c; 但是如果这个老商品是已失效状态&#xff0c;就无法自动移入收藏夹&#xff0c;而且会一直在购物车…

python-study-day1-(病人管理系统-带sql)

MainWindow代码 from tkinter import * from tkinter import messagebox from tkinter.ttk import Comboboxclass MianWindow(Frame):def __init__(self, masterNone):super().__init__(master, padx30, pady20)self.flag 0self.pack(expandTrue, fillBOTH)self.id StringVa…

C语言面试题之合法二叉搜索树

合法二叉搜索树 实例要求 实现一个函数&#xff0c;检查一棵二叉树是否为二叉搜索树&#xff1b; 示例 1: 输入:2/ \1 3 输出: true 示例 2: 输入:5/ \1 4/ \3 6 输出: false 解释: 输入为: [5,1,4,null,null,3,6]。根节点的值为 5 &#xff0c;但是其右子节点值为 4 …

pmp就是智商税?

首先要明白的是&#xff0c;证书的价值并不在于证书本身&#xff0c;而在于学习过程中所获得的知识和经验&#xff0c;这才是证书真正的价值&#xff0c;是无法被复制的个人能力。 学习和考证都是经验的积累&#xff0c;通过这个过程可以不断地获取所需的知识&#xff0c;并加…

Day36|贪心算法part05:435. 无重叠区间、763.划分字母区间、56. 合并区间

435. 无重叠区间 有了上题射气球的因子&#xff0c;这题也就有思路了&#xff0c;反正无脑排序就行了&#xff1a; 首先将所有区间按照end的大小从小到大排序&#xff1b;选取最早end为起始x_end遍历所有区间&#xff0c;如果该区间的start比end大&#xff08;可重叠&#xf…

“揭秘性能测试工具:优化软件性能的关键秘籍“

性能测试工具的设计宗旨是为了模拟用户对软件应用程序或系统的各种操作&#xff0c;旨在评估关键的性能指标&#xff0c;包括响应时间、吞吐量、并发能力和资源利用率。 通过这些工具模拟的多用户环境&#xff0c;我们能够产生与实际工作负载相似的条件&#xff0c;并监测系统…

算法打卡day32

今日任务&#xff1a; 1&#xff09;738.单调递增的数字 2&#xff09;968.监控二叉树 738.单调递增的数字 题目链接&#xff1a;738. 单调递增的数字 - 力扣&#xff08;LeetCode&#xff09; 文章讲解&#xff1a;代码随想录 (programmercarl.com) 视频讲解&#xff1a;贪…

smnpwalk

安装&#xff1a; sudo yum install net-snmp net-snmp-utils 设备MIB文件查看OID&#xff1b; [rootzabbix ~]$snmpwalk -v 2c -c public 192.168.1.100 1.3.6.1.4.1.2011.6.139.12.1.5.7 SNMPv2-SMI::enterprises.2011.6.139.12.1.5.7.0 INTEGER: 62 所以命令也可以写成…

SpringBoot+Vue,轻松实现网页版人脸登录与精准识别

目录 1、技术介绍 2、技术原理 2.1、人脸检测 ①参考模板法 ②人脸规则法 2.2、人脸跟踪 2.3、人脸比对 ①特征向量法 ②面纹模板法 识别过程 案例 一、springboot后端项目 1&#xff0c;拉取项目后&#xff0c;导入相关依赖jar包 2&#xff0c;执行sql文件夹下面…

Lora 串口透传开发 5

1 简介 串口转usb、转wifi等很多应用 2 设计原理 2.1 设计需求 1将LoRa终端定义成两种角色:Master和Slave 2一个模块发送任意字节长度&#xff08;小于128Byte&#xff09;数据&#xff0c;另一模块都可以接收到 3PC机上通过串口调试助手实现接收和发送 4终端在LCD屏幕上显…

【matlab】如何解决打开缓慢问题(如何让matlab在十几秒内打开)

【matlab】如何解决打开缓慢问题&#xff08;如何让matlab在十几秒内打开&#xff09; 找到我们解压缩时Crack中的license_standalone.lic文件&#xff0c;将其拷贝 在安装matlab的路径下新建一个文件&#xff0c;粘贴上面的license_standalone.lic文件 在桌面鼠标移动到matl…

K3 BOS单据中父子字段的问题

因业务需求新增了一张BOS单据&#xff0c;其中涉及到装配工序有两级&#xff0c;需要在选好“一级工序”后&#xff0c;“二级工序”跳出来的是一级工序下的内容&#xff0c;经过咨询分析研究&#xff0c;解决办法如下。 设置过程 在核算项目中原有的工序中先增加“一级工序”…

【电控笔记5】电流环pi参数整定

旋转坐标系下的电压方程&#xff0c;由id和iq计算出ud和uq Lq&#xff1a;q轴电感 Ld&#xff1a;d轴电感 输入是电流&#xff0c;输出是电压&#xff1f; 把常数项&#xff08;上面两个红框&#xff09;拿出来解耦合&#xff0c;作为前馈&#xff0c;如下 电流环传递函数 …

Ansys 结构 | 从力学学科体系说起

“力学是研究物质机械运动的科学” 力学有着悠久的历史&#xff0c;最早可追溯到古希腊的阿基米德(约公元前287 - 212)&#xff0c;并且在欧洲文艺复兴运动以后&#xff0c;人们逐步对力和运动之间的关系有了正确的认识。 英国科学家牛顿继承和发展了前人的研究成果&#xff0…

Navicat的详细下载步骤

第一步&#xff0c;打开百度&#xff0c;找到Navicat官网 第二步&#xff0c;点击产品然后进去 第三步&#xff0c;点击直接下载然后跟着步骤来就OK啦

uniapp 轮播列表一排展示3个,左右滑动,滑动到中间放大

一、效果展示 二、代码实现 1.html代码&#xff1a; <!-- 轮播 --><view class"heade"><swiper class"swiper" display-multiple-items3 circulartrue previous-margin1rpx next-margin1rpxcurrent0 change"swiperChange">&l…

EasyExcel用模版导出动态表格

在工作中有这么一个需求就是导出一个表格&#xff0c;上面有学生的信息下面有一个表格记录学生每科的成绩&#xff0c;要导出这样一个表格我们要怎么做呢&#xff1f;其实很简单&#xff0c;可以用导出模版做到&#xff0c;Easyexcel已经有实现方法了&#xff0c;下面我们来一步…

【Python数据分析】让工作自动化起来,无所不能的Python

这里写目录标题 前言一、Python是办公自动化的重要工具二、Python是提升职场竞争力的利器三、Python是企业数字化的重要平台四、Python是AI发展的重要通道之一编辑推荐内容简介作者简介前言读者对象如何阅读本书目录 前言 随着我国企业数字化和信息化的深入&#xff0c;企业对…