C++----模板进阶

news2024/11/27 20:30:37

文章目录

    • 非类型模板参数
      • STL知识补充
    • 类模板的特化
      • 函数模板特化
      • 类模板特化
        • 偏特化
    • 模板的分离编译
    • 模板总结

非类型模板参数

模板参数分为类型形参与非类型形参

类型形参:出现在模板参数列表中,跟在class或者typename之类的参数类型名称。

非类型形参:就是用一个常量作为类(函数)模板的一个参数,在类(函数)模板中可将该参数当成常量来使用。

在这里插入图片描述

注意:

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

STL知识补充

在STL中有一个和数组几乎一样的类(array类),array类与数组有什么不同呢?

区别

在这里插入图片描述

类模板的特化

概念

通常情况下,使用模板可以实现一些与类型无关的代码,但对于一些特殊类型的可能会得到一些错误的结果,需要特殊处理。

例如:实现了一个专门用来进行小于比较的函数模板

template<class T>
bool Less(T left, T right)
{
 return left < right;
}
int main()
{
	cout << Less(1, 2) << endl; // 可以比较,结果正确
	Date d1(2022, 7, 7);
	Date d2(2022, 7, 8);
	cout << Less(d1, d2) << endl; // 可以比较,结果正确
	Date* p1 = &d1;
	Date* p2 = &d2;
	cout << Less(p1, p2) << endl; // 可以比较,结果错误
 	return 0;
}

Less绝对多数情况下都可以正常比较,但是在特殊场景下就得到错误的结果。
上述示例中,p1指向的d1显然小于p2指向的d2对象,
但是Less内部并没有比较p1和p2指向的对象内容,而比较的是p1和p2指针的地址

此时,就需要对模板进行特化。即:在原模板类的基础上,针对特殊类型所进行特殊化的实现方式

函数模板特化

函数模板的特化步骤:

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

在这里插入图片描述

注意:一般情况下如果函数模板遇到不能处理或者处理有误的类型,为了实现简单通常都是将该函数直接给出。如下:

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

类模板特化

全特化

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

template<class T1, class T2>
class Print
{
public:
	//构造函数
	Print()
	{
		cout << "Print<P1, P2>" << endl;
	}
private:
	T1 _P1;
	T2 _P2;
};

当P1和P2分别是double和int时,我们若是想对实例化的类进行特殊化处理,那么我们就可以对P1和P2分别是double和int时的模板进行特化。

对于P1是double,P2是int的特化如下:

//对于T1是double,T2是int时进行特化
template<>
class Print<double, int>
{
public:
	//构造函数
	Print()
	{
		cout << "Print<double, int>" << endl;
	}
private:
	double _P1;
	int _P2;
};
偏特化

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

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

偏特化有以下两种表现方式:

1.部分特化

将模板参数类表中的一部分参数特化。

// 将第二个参数特化为int
template <class T1>
class Data<T1, int>
{
public:
 	Data() 
    {
        cout<<"Data<T1, int>" <<endl;
    }
private:
 	T1 _d1;
 	int _d2;
};

2.参数更进一步的限制

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

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

在这里插入图片描述

模板的分离编译

什么是分离编译

一个程序(项目)由若干个源文件共同实现,而每个源文件单独编译生成目标文件,最后将所有目标文件链

接起来形成单一的可执行文件的过程称为分离编译模式。

模板的分离编译

模板的声明与定义分离开,在头文件中进行声明,源文件中完成定义

// a.h
template<class T>
T Add(const T& left, const T& right);
// a.cpp
template<class T>
T Add(const T& left, const T& right)
{
 	return left + right;
}
// main.cpp
#include"a.h"
int main()
{
 	Add(1, 2);
 	Add(1.0, 2.0);
 	return 0;
}

在这里插入图片描述

解决方法

  1. 声明和定义放到一个文件 “xxx.hpp” 里面或者xxx.h其实也是可以的。推荐使用这种。
  2. 模板定义的位置显式实例化。这种方法不实用,不推荐使用。

模板总结

优点:

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

缺陷:

  1. 模板会导致代码膨胀问题,也会导致编译时间变长。
  2. 出现模板编译错误时,错误信息非常凌乱,不易定位错误。

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

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

相关文章

Vue性能优化:加速你的应用

目录 1. 使用虚拟DOM 2. 合理使用计算属性和侦听器 3. 懒加载组件 4. 合理使用v-if和v-show 5. 使用Key管理列表渲染 6. 避免不必要的Watcher 7. 缓存响应式数据 8. 使用异步组件 9. 使用Webpack进行代码优化 10. 监控性能并进行优化 Vue.js是一款流行的JavaScript框…

东软集团:看似低调,却有了19年的AI坚持

【科技明说 &#xff5c; 重磅专题】 在AI领域的专注与研究&#xff0c;东软集团是一个低调的存在。 可能很多人不太了解东软集团对于AI的专心与专注以及专业。三专可以简单概括东软集团的AI雄心壮志。 专注在于&#xff0c;早在2004年&#xff0c;东软就开始启动人工智能技…

【Apache Flink】流式分析的多种应用场景

文章目录 0. 前言1. 数据处理架构的演进2. 传统数据处理架构3. 事务型处理4. 分析型处理用于数据分析的传统数据仓架构 状态化流处理5. 事件驱动型应用什么是事件驱动型应用&#xff1f; 6. 数据管道什么是数据管道&#xff1f;Flink 如何支持数据管道应用&#xff1f;典型的数…

二叉树三种遍历的递归与非递归写法

目录 ​编辑 一&#xff0c;前序遍历 题目接口&#xff1a; 递归解法&#xff1a; 非递归解法&#xff1a; 二&#xff0c;中序遍历 题目接口&#xff1a; 递归解法&#xff1a; 非递归写法&#xff1a; 三&#xff0c;后序遍历 题目接口&#xff1a; 递归解法&…

IOC课程整理-17 Spring事件

1. Java 事件/监听器编程模型 2. 面向接口的事件/监听器设计模式 3. 面向注解的事件/监听器设计模式 4. Spring 标准事件-ApplicationEvent 5. 基于接口的 Spring 事件监听器 6. 基于注解的 Spring 事件监听器 7. 注册 Spring ApplicationListener 8. Spring 事件发布器 9. Spr…

基于VectorGrid加载GeoServer发布的矢量瓦片实例

目录 前言 一、关于VectorGrid 1、开源地址 2、本地示例 二、与LeafLet集成 1、新建html页面 2、地图初始化 3、pbf瓦片地址配置 4、pbf初始化 三、GeoServer跨域问题 1、web.xml配置 2、重启tomcat 总结 前言 回望10月&#xff0c;发生了一些变动&#xff0c;面向未…

状态机图和活动图

在面向对象软件分析过程中&#xff0c;状态机图和活动图用于建立软件的动态模型&#xff0c;主要描述系统随时间变化的行为。 1.状态图 1.1概念 状态图用来描述对象状态和事件之间的关系&#xff0c;强调一个实体基于事件反应的动态行为。状态图适合用于表述在不同用例之间的…

C语言#error和#line

C语言#error和#line #error #error用于生成一个编译错误消息&#xff0c;并停止编译 示例&#xff1a; 随便找了一个工程测试下#error 看图中我圈起来的部分&#xff0c;编译器提示warning和error。看我的程序如果没有定义TEST_#ERROR这个宏&#xff0c;编译器会报错You di…

我是如何快速从python小白达到20k?

前言 首先说一下我自己的情况&#xff0c;我之前是学JAVA的&#xff0c;JAVA亡了只好转行python 很多新手就在好奇自己明明都认认真真的学习了python&#xff0c;但就是感觉很杂很乱&#xff0c;按照我这个流程&#xff0c;至少可以省一大半时间&#xff0c;完整的知识体系很重…

LED主流光源-环形光源

1&#xff09;产品特点&#xff1a; ① 环形光源提供不同角度照射&#xff0c;能突出物体的三维信息有效的解决对角照射阴 影问题&#xff1b; ② 周围表面采用滚花设计&#xff0c;扩大散热面积保障光源的使用寿命&#xff1b; ③ 根据客户不同需求可 选配不同漫射板&#xff…

AIGC如何助力产品研发的创新和性能提升

1、现有的产品和系统的升级 a&#xff09;、关键算法的替换&#xff0c;用深度学习来替换&#xff0c;用数学来描述&#xff1a; 需要定义好中间状态的和&#xff0c;总体过程是,中间的过程,替换为。 总体过程表示成下面的方式: 完成替换过程&#xff1a; 。 b&#xff09;…

vivado窗口使用与分析2-IDE 中的逻辑分析

逻辑分析 包括 &#xff1a; • “ Netlist ”窗口 • “ Hierarchy ”窗口 • “ Schematic ”窗口 1、 “ Netlist ”窗口 “ Netlist ” &#xff08; 网表 &#xff09; 窗口显示了网表中由综合工具所处理的设计层级。 根据综合设置 &#xff0c; 网表层级与原始 RT…

【网络】序列化反序列化

序列化反序列化 一、序列化反序列化1、概念2、序列化作用3、序列化框架的选择 二、Json1、介绍2、简单使用 一、序列化反序列化 1、概念 在前文《网络编程套接字》中&#xff0c;我们实现了服务器与客户端之间的字符串通信&#xff0c;这是非常简单的通信&#xff0c;在实际使…

JavaScript从入门到精通系列第二十五篇:JavaScript中的Date对象

文章目录 一&#xff1a;Date对象简介 1&#xff1a;概念简介 二&#xff1a;Date对象 1&#xff1a;创建当前时间 2&#xff1a;创建指定时间 三&#xff1a;日期对象函数 1&#xff1a;getDate() 2&#xff1a;getDay() 3&#xff1a;getMonth() 4&#xff1a;getF…

基于springboot环保话题管理系统-计算机毕设 附源码 28550

springboot环保话题管理系统 摘 要 随着科学技术的飞速发展&#xff0c;社会的方方面面、各行各业都在努力与现代的先进技术接轨&#xff0c;通过科技手段来提高自身的优势&#xff0c;中小型企业当然也不能排除在外。环保话题管理系统是以实际运用为开发背景&#xff0c;运用软…

Flask路由机制分析之二

一、前言 上篇 《Flask 路由机制分析之一》主要讲了Python函数的特性以及装饰器的基本概念&#xff0c;这节我们具体分析一下路由内部机制&#xff0c;Flask路由依赖于werkzegu的routing模块来实现。 二、werkzegu的routing模块介绍 Werkzegu库的routing模块主要功能在于URL…

iMazing2024年最新许可证-iMazing许可证激活补丁

《iMazing》2024年最新许可证&#xff0c;iMazing 号称是 Mac 和PC上最好的iOS设备管理器。iMazingapp还可以帮助用户轻松地管理应用程序&#xff0c;可以方便的进行拷贝&#xff0c;安装&#xff0c;删除和更新应用程序。它可以帮助用户轻松访问文件系统&#xff0c;并可以轻松…

使用FastAPI部署Ultralytics YOLOv5模型

YOLO是You Only Look Once(你只看一次)的缩写&#xff0c;它具有识别图像中的物体的非凡能力&#xff0c;在日常应用中会经常被使用。所以在本文中&#xff0c;我们将介绍如何使用FastAPI的集成YOLOv5&#xff0c;这样我们可以将YOLOv5做为API对外提供服务。 Python有几个web框…

深入探究Python中的深度学习:神经网络与卷积神经网络

当下&#xff0c;深度学习已经成为人工智能研究和应用领域的关键技术之一。作为一个开源的高级编程语言&#xff0c;Python提供了丰富的工具和库&#xff0c;为深度学习的研究和开发提供了便利。本文将深入探究Python中的深度学习&#xff0c;重点聚焦于神经网络与卷积神经网络…

基于springboot实现校园台球厅人员与设备系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现校园台球厅人员与设备系统演示 摘要 在Internet高速发展的今天&#xff0c;我们生活的各个领域都涉及到计算机的应用&#xff0c;其中包括校园台球厅人员与设备管理系统的网络应用&#xff0c;在外国管理系统已经是很普遍的方式&#xff0c;不过国内的管理网…