【C++】学习笔记——模板进阶

文章目录

  • 十一、模板进阶
    • 1. 非类型模板参数
    • 2. 按需实例化
    • 3. 模板的特化
      • 类模板的特化
    • 4. 模板的分离编译
  • 未完待续


十一、模板进阶

1. 非类型模板参数

模板参数分为类型形参和非类型形参类型形参即:出现在模板参数列表中,跟在class或者typename之类的参数类型名称非类型形参,就是用一个常量作为类(函数)模板的一个参数,在类(函数)模板中可将该参数当成常量来使用

// 第一个形参为类型形参,第二个缺省形参为非类型形参
template<class T, size_t N = 10>
#include<iostream>
using namespace std;

template<class T, size_t N>
class arr
{
	// N可以用来分配初始空间
};

int main()
{
	arr<int, 10> a1;
	arr<int, 1000> a2;

	return 0;
}

在C++20之前,只支持整形做非类型模板参数

2. 按需实例化

类模板在实例化这个类的时候,会按需实例化(调用了哪个成员函数就实例化哪个函数) 。

#include<iostream>
using namespace std;

template<class T, size_t N>
class arr
{
public:
	T& operator[](size_t index)
	{
		// 该函数参数不匹配
		size(1);
		return _array[index];
	}

	const T& operator[](size_t index)const
	{
		return _array[index];
	}

	size_t size()const { return _size; }
	bool empty()const { return 0 == _size; }

private:
	T _array[N];
	size_t _size;
};

int main()
{
	// 不去调用 operator[] 时,检查不出来错误
	arr<int, 10> a1;
	arr<int, 1000> a2;
	return 0;
}

在这里插入图片描述
当调用出错的部分的函数时才能检查出错误:

int main()
{
	// 不去调用 operator[] 时,检查不出来错误
	arr<int, 10> a1;
	arr<int, 1000> a2;
	// 调用operator[]
	a1[1];
	return 0;
}

在这里插入图片描述

3. 模板的特化

通常情况下,使用模板可以实现一些与类型无关的代码,但对于一些特殊类型的可能会得到一些错误的结果。比如说我们有这样一个函数模板:

template<class T>
bool less(T left, T right)
{
	return left < right;
}

该函数模板可以比较大小,但是假如有人错误的传入 地址 当实参,这里必然会出现不确定的结果。如果我们想要传地址也让其结果正确的话,我们就可以使用 模板的特化 。特化就是将模板特殊化,在原模板类的基础上,针对特殊类型所进行特殊化的实现方式。即新增一个特化后的模板。

#include<iostream>
using namespace std;

// 函数模板
template<class T>
bool Less(T left, T right)
{
	return left < right;
}

// 特化后的模板
template<>
bool Less<int*>(int* left, int* right)
{
	return left < right;
}

此时,要是实例化的参数更符合特化就使用特化模板进行实例化,否则使用普通的函数模板进行实例化。

函数模板的特化步骤:

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

一般情况下如果函数模板遇到不能处理或者处理有误的类型,为了实现简单通常都是将该函数直接给出,即直接实现一个特殊的函数构成重载。

bool Less(Date* left, Date* right)
{
 return *left < *right;
}

该种实现简单明了,代码的可读性高,容易书写,因此函数模板不建议特化。

类模板的特化

类模板特化也分为 全特化偏特化
全特化即是将模板参数列表中所有的参数都确定化。偏特化是任何针对模版参数进一步进行条件限制设计的特化版本

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

// 全特化
template<>
class Data<int, char>   // 参数都全部给定
{
public:
	Data()
	{
		cout << "Data<int, char>" << endl;
	}
private:
	int _d1;
	char _d2;
};

// 半特化/偏特化
template<class T>
class Data<T, char>     // 不是全特化的特化
{
public:
	Data()
	{
		cout << "Data<T, char>" << endl;
	}
private:
	int _d1;
	char _d2;
};

类模板的偏特化还可以这样使用:

//两个参数偏特化为指针类型 
template <class T1, class T2>
class Data<T1*, T2*>
{
public:
	Data()
	{
		cout << "Data<T1*, T2*>" << endl;
	}
private:
	T1 _d1;
	T2 _d2;
};

偏特化并不仅仅是指特化部分参数,而是针对模板参数更进一步的条件限制所设计出来的一个特化版本

4. 模板的分离编译

模板不建议声明和定义分离 。当声明和定义分离时,声明处有调用,所以知道模板实例化的类型,但是没有实现功能,定义处没有调用,可以实现功能但是不知道实例化的类型,所以定义处在编译时,并不会生成地址,导致链接时找不到地址从而产生链接错误。

在这里插入图片描述
解决方法有两种:①模板定义的位置显式实例化。(这种方法不实用,不推荐使用)②不进行声明和定义分离,将定义也放在.h头文件里


未完待续

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

经典权限五张表功能实现

文章目录 用户模块(未使用框架)查询功能实现步骤代码 新增功能实现步骤代码 修改功能实现步骤代码实现 删除功能实现步骤代码实现 用户模块会了&#xff0c;其他两个模块与其类似 用户模块(未使用框架) 查询功能 这里将模糊查询和分页查询写在一起 实现步骤 前端&#xff1…

泵站远程监控

在科技日新月异的今天&#xff0c;智能化管理已经成为各行业提升效率、降低成本的关键手段。特别是在水利领域&#xff0c;泵站作为水资源调配的重要节点&#xff0c;其运行效率和安全稳定性直接关系到整个供水系统的稳定。HiWoo Cloud平台凭借其强大的物联网和云计算技术&…

两重惊喜!奥特曼预告GPT-4和ChatGPT重大更新,Open AI要放大招

OpenAI在今天官宣13日&#xff08;下周一10点&#xff09;开启线上直播&#xff0c;将会展示全新的ChatGPT demo的演示以及GPT-4的重大更新&#xff01; OpenAI首席执行官Sam Altman在X上表示&#xff0c;这些的发布会&#xff0c;公司不会宣布下一代对话式人工智能GPT-5或人工…

游戏安全干货报告干货下载 |《2023年度游戏安全观察与实践报告》

AIGC浪潮从大洋彼岸袭来&#xff0c;使得全球资本市场看好AIGC将对游戏行业“成本”与“效率”带来革命性的变化&#xff1b;年末&#xff0c;国家新闻出版署一次性批准了105款国产游戏版号&#xff0c;为历史之最&#xff1b;全年亦有不少“某某大厂裁撤游戏业务”、“某某游戏…

C语言写扫雷游戏(数组和函数实践)

目录 最后是代码啦&#xff01; 手把手教你用C语言写一个扫雷游戏&#xff01; 1.我们搭建一下这个多文件形式的扫雷游戏文件结构 2.在主函数里面设置一个包含游戏框架的菜单 菜单可以方便游戏玩家选择要进行的动作和不断地进行下一局。 3.switch语句连接不同的结果 菜单可…

C++实现一个简单的控制cpu利用率的程序

写一个程序&#xff0c;让控制cpu利用率在20%左右 思路很简单&#xff1a;每个循环控制sleep的时间占比 #include <iostream> #include <chrono> #include <unistd.h>int main() {int ratio 20;int base_time 1000;int sleeptime base_time * (100-ratio…

信息系统架构模型_3.企业数据交换总线

1.企业数据交换总线 实践中&#xff0c;还有一种较常用的架构&#xff0c;即企业数据交换总线&#xff0c;即不同的企业应用之间进行信息交换的公共通道&#xff0c;如图1所示。 图1 企业数据交换总线架构 这种架构在大型企业不同应用系统进行信息交换时使用较普遍&am…

uniapp管理后台编写,基于uniadmin和vue3实现uniapp小程序的管理后台

一&#xff0c;创建uniAdmin项目 打开开发者工具Hbuilder,然后点击左上角的文件&#xff0c;点新建&#xff0c;点项目。如下图。 选择uniadmin&#xff0c;编写项目名&#xff0c;然后使用vue3 记得选用阿里云服务器&#xff0c;因为最便宜 点击创建&#xff0c;等待项目创…

2024年4月12日饿了么春招实习试题【第三题】-题目+题解+在线评测,2024.4.12,饿了么机试【Kruskal 算法, 最小生成树】

2024年4月12日饿了么春招实习试题【第三题】-题目题解在线评测&#xff0c;2024.4.12&#xff0c;饿了么机试 &#x1f3e9;题目一描述&#xff1a;样例1样例2解题思路一&#xff1a;[Kruskal 算法](https://baike.baidu.com/item/%E5%85%8B%E9%B2%81%E6%96%AF%E5%8D%A1%E5%B0%…

牛客网Java实战项目--仿牛客网社区的学习笔记

仿牛客网社区的学习笔记 1. 项目环境搭建1.1 开发社区首页 2.开发社区登录模块2.1 发送邮件2.2 开发注册功能2.3 会话管理2.4 生成验证码2.5 开发登录、退出功能2.6 显示登录信息 4 Redis实现点赞关注4.1 Spring整合Redis访问Redis的方法&#xff1a; 4.2 Redis实现点赞4.2.1 点…

Git系列:git merge 使用技巧

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

Redis基础面试知识点(1)

相比于C字符串&#xff0c;SDS的优势&#xff1a; O(1)获取字符串的长度不会缓冲区溢出减少修改字符串时所需的内存重新分配的次数&#xff08;空间预分配、惰性空间释放&#xff09;二进制API安全&#xff08;通过len获取长度&#xff09;兼容部分C字符串函数 Redis hash策略…

SpringAMQP Work Queue 工作队列

消息模型: 代码模拟: 相较于之前的基础队列&#xff0c;该队列新增了消费者 不再是一个&#xff0c;所以我们通过代码模拟出两个consumer消费者。在原来的消费者类里写两个方法 其中消费者1效率高 消费者2效率低 RabbitListener(queues "simple.queue")public voi…

机器学习算法应用——CART决策树

CART决策树&#xff08;4-2&#xff09; CART&#xff08;Classification and Regression Trees&#xff09;决策树是一种常用的机器学习算法&#xff0c;它既可以用于分类问题&#xff0c;也可以用于回归问题。CART决策树的主要原理是通过递归地将数据集划分为两个子集来构建决…

【nodejs 命令行交互神器 - inquirer.js】

需求 大家在开发时&#xff0c;有时需要从命令行读取用户的输入&#xff0c;或者让用户选择。在nodejs中&#xff0c;这个怎么实现? 原生实现 ❌ process.stdin.setEncoding(utf8);process.stdin.on(readable, () > {let chunk;// 使用循环确保我们读取所有的可用输入wh…

【C++算法】队列相关经典算法题

1. N叉树的层序遍历 首先我们遇到这个题目&#xff0c;没有任何思路&#xff0c;我们就可以来模拟一下层序的流程&#xff0c;首先我们肯定是访问根节点1&#xff0c;访问之后呢就是访问下一层的最左节点3&#xff0c;此时第一层的节点1已经访问过了就可以不要了&#xff0c;然…

词令蚂蚁新村今日答案:微信小程序怎么查看蚂蚁新村今天问题的正确答案?

微信小程序怎么查看蚂蚁新村今天问题的正确答案&#xff1f; 1、打开微信&#xff0c;点击搜索框&#xff1b; 2、打开搜索页面&#xff0c;选择小程序搜索&#xff1b; 3、在搜索框&#xff0c;输入词令搜索点击进入词令微信小程序&#xff1b; 4、打开词令微信小程序关键词口…

每日10亿数据的日志分析系统OOM

背景 一个每日10亿数据的日志清洗系统&#xff0c;主要工作就是从消息队列中消费各种各样的日志&#xff0c;然后对日志进行清洗&#xff0c;例如&#xff1a;用户敏感信息(姓名、手机号、身份证)进行脱敏处理,然后把清理完的数据交付给其他系统使用。 我们项目中&#xff0c;…

设计模式2——原则篇:依赖倒转原则、单一职责原则、合成|聚合复用原则、开放-封闭原则、迪米特法则、里氏代换原则

设计模式2——设计原则篇 目录 一、依赖倒转原则 二、单一职责原则&#xff08;SRP&#xff09; 三、合成|聚合复用原则&#xff08;CARP&#xff09; 四、开放-封闭原则 五、迪米特法则&#xff08;LoD&#xff09; 六、里氏代换原则 七、接口隔离原则 八、总结 一、依赖…

《2024年AI安全报告》:AIML工具使用量飙升594.82%

人工智能&#xff08;AI&#xff09;不仅仅是一种开拓性的创新技术&#xff0c;甚至已经成为一种常态&#xff0c;企业正在工程、IT营销、财务、客户服务等领域迅速采用AI和机器学习&#xff08;ML&#xff09;工具。但与此同时&#xff0c;他们必须平衡AI工具带来的诸多风险&a…