c++ - 模板(二)

文章目录

    • 一、模板参数缺省值
    • 二、非类型模板参数
    • 三、模板的特化
    • 四、模板的分离编译


一、模板参数缺省值

给模板初始值与给函数初始值类似,当需要给一部分缺省值时,参数缺省值必须从右向左给,中间不能留着参数不给缺省值。

template< class T = int>
void test01()
{
	cout << "T: "<<typeid(T).name() << endl;
}

template<class T1, class T2 = int>
void test02()
{
	cout << "T1: "<<typeid(T1).name() << endl;
	cout << "T2: "<<typeid(T2).name() << endl;
}

int main()
{
	//使用默认缺省值
	test01();

	//指定
	test01<double>();

	//部分缺省
	test02<double>();

	//全部指定
	test02<double,double>();

	return 0;
}

在这里插入图片描述

二、非类型模板参数

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

//T为类型,N为常量
template< class T, size_t N>
class Arr
{
public:
	Arr()
	{
		cout << N << endl;
	}

private:
	int arr[N] = {0};
};

int main()
{
	Arr<int, 10> arr;
	return 0;
}

在这里插入图片描述

注意:

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

三、模板的特化

1、函数模板特化
有一些场景只通过通用的函数模板是无法求正确答案的。
如:

template< class T>
void Sub(T a,T2 )
{
	cout << a - b << endl;
}

int main()
{
	int a = 20;
	int b = 10;

	//没有问题
	Sub(a, b);

	//出错了,求的是指针的差
	Sub(&a, &b);

	return 0;
}

在这里插入图片描述

对于上面情况可以通过函数模板特化解决
函数模板的特化步骤:

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


template<>
void Sub<int*>(int* a, int* b)
{
	cout << *a - *b << endl;

}
int main()
{
	int a = 20;
	int b = 10;

	//没有问题
	Sub(a, b);

	//使用特化的模板
	Sub(&a, &b);

	return 0;
}

在这里插入图片描述
另一种解决方法就是直接写一个该类型的函数,这个函数会与模板函数构成重载,并且符合的话会被优先使用

template< class T>
void Sub(T a,T b)
{
	cout <<"void Sub(T a,T b)"<< endl;
}

void Sub(int* a, int* b)
{
	cout <<"void Sub(int* a, int* b)" << endl;
}
int main()
{
	int a = 20;
	int b = 10;
	 
	//使用模板
	Sub(a, b);

	//使用现成函数
	Sub(&a, &b);

	return 0;
}

在这里插入图片描述
2、类模板特化
类特化的方式与函数模板特化参不多,就是原本在函数名指定改为在类名指定。
(1)全特化
全特化就是全部参数被指定。

template<class T1,class T2>
class A
{
public:
	A() { cout<<"class A" << endl; }
};

template<>
class A<int,char>
{
public:
	A() { cout << "class A<int,char>" << endl; }
};

int main()
{
	//调用通用模板
	A<int, int> a1;

	//使用特化模板
	A<int, char> a2;

	return 0;
}

在这里插入图片描述
(2)偏特化
只特化一部分参数:
在这里插入图片描述
限定参数:

template<class T1, class T2>
class A
{
public:
	A() { cout << "class A" << endl; }
};

template<class T1,class T2>
class A<T1*, T2*>
{
public:
	A() { cout << "class A<T1*, T2*>" << endl; 
	cout <<"T1:" << typeid(T1).name() << endl;
	}
};

template<class T1, class T2>
class A<T1&, T2&>
{
public:
	A() { cout << "class A<T1&, T2&>" << endl;
	cout << "T1:" << typeid(T1).name() << endl;
	}
};

int main()
{
	//调用通用模板
	A<int, int> a1;

	//使用特化模板
	//虽然传的是int*,但是T1还是int
	A<int*, int*> a2;

	//虽然传的是double&,但是T1还是double
	A<double&, double&> a3;
	
	return 0;
}

在这里插入图片描述

四、模板的分离编译

1、关于类模板实例化:
例:

template<class T>
class A
{
public:
	//重命名
	typedef T TYPE;
};

template<class T>
void test03()
{
	//会检查语法等
	A<T>::TYPE a = 10;
}

int main()
{
	test03<int>();
	return 0;
}

在这里插入图片描述

在没有被实例化时,编译器只会对函数进行语法等检查,不会查看类内部细节,如上面的A<T>::TYPE a = 10 TYPE是类型按道理来说没有问题,但是编译器在检查到这里是就会出现歧义,不知道TYPE是类型还是静态变量,所以就会报错。

对于上述这种情况,我们可以加一个 typename 关键字来说明TYPE是一个类型,这样就不会报错了。

typename A<T>::TYPE a = 10;

2、什么是分离编译
一个程序(项目)由若干个源文件共同实现,而每个源文件单独编译生成目标文件,最后将所有目标文件链
接起来形成单一的可执行文件的过程称为分离编译模式。

3、为什么模板分离编译会报错
在这里插入图片描述

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

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

相关文章

Ubuntu系统装显卡驱动

英文地址&#xff1a;https://www.nvidia.com/Download/Find.aspx?langen-us# 中文地址&#xff1a;https://www.nvidia.cn/Download/index.aspx?langcn# sudo apt-get updatesudo apt-get install gsudo apt-get install gccsudo apt-get install makesudo gedit /etc/modp…

圈子社区系统源码 开源 多端圈子社区论坛系统 社区圈子管理系统

介绍 圈子论坛小程序&#xff0c;是一款为用户提供交流分享、互动沟通的平台。在这个小程序中&#xff0c;用户可以轻松地加入各种不同兴趣爱好的圈子&#xff0c;与志同道合的朋友们交流互动。圈子论坛小程序不仅仅是一个简单的社交工具&#xff0c;更是一个打开新世界大门的…

Mybatis不明白?就这一篇带你轻松入门

引言&#xff1a;烧脑的我一直在烧脑的寻找资料&#xff0c;寻找网课&#xff0c;历经磨难让一个在大一期间只会算法的我逐渐走入Java前后端开发&#xff0c;也是一直在自学的道路上磕磕碰碰&#xff0c;也希望这篇文章对于也是同处于自学的你有所帮助&#xff0c;也希望你继续…

MyBatis框架——快速入门

MyBatis 是一款优秀的持久层框架&#xff0c;用于简化JDBC开发 MyBatis 本是Apache 的一个开源项目iBatis,2010年这个项目由apache softwarefoundation 迁移到了google code&#xff0c;并且改名为MyBatis 。2013年11月迁移到Github 官网: https://mybatis.org/mybatis-3/zh/…

初识C++ · 优先级队列

目录 前言&#xff1a; 1 优先级队列的使用 2 优先级队列的实现 3 仿函数 前言&#xff1a; 栈和队列相对其他容器来说是比较简单的&#xff0c;在stl里面&#xff0c;有一种容器适配器是优先级队列&#xff08;priority_queue&#xff09;&#xff0c;它也是个队列&#…

连锁门面电能监测系统是什么?

1.什么叫连锁门面电能监测系统 连锁门面电能监测系统是一种前沿的能源管理体系系统&#xff0c;针对连锁加盟店铺的电力应用情况进行实时监控及管理。这类系统根据集成化硬件配置和软件系统&#xff0c;能够帮助企业管理人员获得每个门店的电力耗费数据信息&#xff0c;进而实…

企业文件加密:数据保护的实战策略

数据是企业的生命线&#xff0c;保护数据安全就是保护企业的竞争力。在众多数据保护措施中&#xff0c;文件加密因其直接有效而备受青睐。 一、为何文件加密至关重要 在数字化办公时代&#xff0c;企业机密和敏感数据的泄露可能带来毁灭性的后果。文件加密能够确保即使数据被盗…

费效看板,YonSuite商旅费控助力企业“消灭报销”

在快速变化的商业环境中&#xff0c;差旅费用作为企业运营成本的重要组成部分&#xff0c;其管理和控制日益受到企业的重视。传统的报销流程繁琐、效率低下&#xff0c;不仅增加了企业的管理成本&#xff0c;也影响了员工的差旅体验。YonSuite商旅费控系统以其费效看板功能为核…

区间预测 | Matlab实现QRCNN-BiGRU-Attention分位数回归卷积双向门控循环单元注意力机制时序区间预测

区间预测 | Matlab实现QRCNN-BiGRU-Attention分位数回归卷积双向门控循环单元注意力机制时序区间预测 目录 区间预测 | Matlab实现QRCNN-BiGRU-Attention分位数回归卷积双向门控循环单元注意力机制时序区间预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实…

磁盘未格式化:深度解析、恢复方案及预防之道

在当今这个信息化爆炸的时代&#xff0c;磁盘未格式化问题无疑成为了众多用户头疼的难题。当我们的存储设备突然提示“磁盘未格式化”时&#xff0c;数据的丢失与恢复的挑战便摆在了我们面前。本文将深入解析磁盘未格式化的现象、原因&#xff0c;并给出两种有效的数据恢复方案…

Master-Worker 架构的灰度发布难题

作者&#xff1a;石超 一、前言 Master-Worker 架构是成熟的分布式系统设计模式&#xff0c;具有集中控制、资源利用率高、容错简单等优点。我们数据中心内的几乎所有分布式系统都采用了这样的架构。 &#xfeff; 我们曾经发生过级联故障&#xff0c;造成了整个集群范围的服…

创建 MFC DLL-使用DEF文件

本文仅供学习交流&#xff0c;严禁用于商业用途&#xff0c;如本文涉及侵权请及时联系本人将于及时删除 利用“MFC动态链接库”项目模板可以创建MFC DLL。DLL文件与可执行文件非常相似&#xff0c;不同点在于DLL包含有导出表(Export Table)。导出表包含DLL中每个导出函数的名字…

实时库存同步与并发控制:确保在线扭蛋机商品库存的实时准确性

随着电商的飞速发展&#xff0c;在线扭蛋机作为一种新兴的销售模式&#xff0c;受到了广大消费者的喜爱。然而&#xff0c;如何在大量用户同时购买时&#xff0c;确保库存信息的实时性和准确性&#xff0c;成为了摆在商家面前的一大挑战。本文将探讨如何设计一个高效且准确的库…

鸿蒙轻内核M核源码分析系列四 中断Hwi

在鸿蒙轻内核源码分析系列前几篇文章中&#xff0c;剖析了重要的数据结构。本文&#xff0c;我们讲述一下中断&#xff0c;会给读者介绍中断的概念&#xff0c;鸿蒙轻内核的中断模块的源代码。本文中所涉及的源码&#xff0c;以OpenHarmony LiteOS-M内核为例。 1、中断概念介绍…

连锁酒店水电监测管理系统

1.前言&#xff1a; 连锁酒店水电监测管理系统是当代酒店业中不可或缺智能化专用工具&#xff0c;主要是通过实时监控系统和数据分析&#xff0c;完成了对酒店电力能源所使用的精益化管理&#xff0c;减少了经营成本&#xff0c;提高了服务水平&#xff0c;并且也响应了绿色环…

centos7安装 hadoop集群

目录 准备集群搭建步骤1. 环境准备三台服务器IP关闭三台服务器的防火墙修改三台服务器的hostname文件修改三台服务器的hosts映射配置三台服务器之间的免密登录三台时间同步设置 2. hadoop安装资源划分3. 开始搭建hadoop集群192.168.83.144 即 hadoop1上的修改解压安装包添加环境…

R可视化:可发表的热图

当使用pheatmap包在R语言中实现不同组间的基因表达热图时,我们通常遵循以下步骤: 步骤 1: 加载所需的库首先,我们需要加载pheatmap包以及可能需要的其他包,如dplyr或tidyverse,用于数据预处理。 步骤 2: 准备数据我们需要一个基因表达矩阵,其中行代表基因,列代表样本,每…

非递归实现快排排序及归并排序(尾篇)

1.快速排序&#xff08;双指针实现&#xff09; 2.非递归实现快排 3.递归实现归并排序 4.非递归实现归并排序 5.总代码 1.快速排序&#xff08;双指针实现&#xff09; 俩有个指针一前一后的排放着&#xff0c;cur先走并且去找比kye对应值小的数组值&#xff0c;一旦找到后…

odoo qweb template小结

QWeb QWeb是一个基于XML的模板引擎,可用于生成HTML片段和页面。它使用XML格式来定义模板。QWeb通过在模板中添加特定的标记,来指示模板中的数据和逻辑部分。使用QWeb,你可以创建各种不同的模板,例如列表视图,表单视图和报告等。QWeb支持标准的HTML标记和控制结构,如if语…

千云物流 -openGemini生成环境使用

部署架构 安装部署 ## 创建storeclass和namespacekubectl apply -f opengemini-sc.yaml## 创建存储kubectl apply -f opengemini-stroepv.yaml #创建存储的pv&pvckubectl apply -f opengemini-metapv.yaml #创meta的pv&pvc## 创建网络服务kubectl apply -f opengemin…