模板进阶和反向迭代器

文章目录

  • 模板
    • 非类型模板参数
    • 模板特化
      • 函数模板特化
      • 类模板特化
    • 模板分离编译
  • 反向迭代器

模板

非类型模板参数

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

在这里插入图片描述
注意:

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

模板特化

通常情况下,使用模板可以实现一些与类型无关的代码,但对于一些特殊类型的可能会得到一些错误的结果,需要特殊处理。比如两个数比较的话,如果参数是指针的话,就不能正常的用大于小于会比较,应该先解引用在比较,否则就会导致结果与我们预期的相反。
模板特化中分为函数模板特化与类模板特化。

函数模板特化

在这里插入图片描述
此时,就需要对模板进行特化。即:在原模板类的基础上,针对特殊类型所进行特殊化的实现方式。
在这里插入图片描述
一般情况下如果函数模板遇到不能处理或者处理有误的类型,为了实现简单通常都是将该函数直接给出。

在这里插入图片描述

该种实现简单明了,代码的可读性高,容易书写,因为对于一些参数类型复杂的函数模板,特化时特别给出(可以构成函数重载),因此函数模板不建议特化,建议直接使用函数重载。

类模板特化

  1. 全特化

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

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;
};
  1. 偏特化

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

部分特化

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

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

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

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

模板分离编译

什么是分离编译呢?

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

我们在写模版分离编译的时候会发现出现链接错误,这是因为我们在主函数中使用了模版函数,我们有这个函数的声明,所以在编译期间不会报错,但是在实现模版函数的那个.cpp文件中并不知道我们要的是什么类型,并没有给我们实例化出相应的代码,所以会出现找不到外部符号。

在这里插入图片描述
解决这个问题有两种方法:

  1. 显示实例化
    但是这种方法很局限,并不适合长久之计。
  2. 将声明和定义放到一个文件"xxx.hpp"里面或者xxx.h其实也是可以的。
    我们一般都使用方法二。

总结

优点:

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

缺点:

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

反向迭代器

反向迭代器我们可以直接将整型迭代器复制一个,然后改一下操作,就可以实现出来我们正常人能够想到的一个反向迭代器版本。我们今天来学习学习大佬的思路,我们会发现正向迭代器和反向迭代器他们的大部分功能都是语一样的,那我们可不可以用一个正向迭代器,用我们的适配器适配出来一个反向迭代器呢?

这个反向迭代器,不仅仅使用于我们的一个容器,而是适用于我们的所有容器。

在这里插入图片描述
在这里插入图片描述

我们通过图,不难发现我们在访问之前先访问end()的前一个元素然后等到迭代器停止时,就可以拿到容器中所有元素。只不过,我们的反向迭代器是反着来的,对于++就是正向迭代器的–,所以我们就可以通过这样的一个想法,来通过一个正向迭代器适配出一个反向迭代器,但是还有一个问题就是,我们并不知道容器中元素的类型,其实这个也好说,我们在实例化模板是直接传过来就可以了。类似于正向迭代器的const于非const版本一样。这样我们不仅能实现一个非const的反向迭代器,连const版本的也实现好了。

template <class Iteraior,class Ref,class Ptr>
class Reverse_iterator
{
public:typedef Reverse_iterator<Iteraior, Ref, Ptr> self;Reverse_iterator(const Iteraior& it):_it(it){}self& operator++(){--_it;return *this;}self operator++(int){self tmp = *this;--_it;return tmp;}bool operator!=(const self& s){return _it != s._it;}bool operator==(const self& s){return _it == s._it;}Ref operator*(){Iteraior tmp = _it;return *(--tmp);}Ptr operator->(){return &(*_it);}
private:Iteraior _it;
};

那么今天的分享就到这里了,有什么不懂得可以私信博主,或者添加博主的微信,欢迎交流。

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

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

相关文章

【Android】关于touch设备TOOL_TYPE_STYLUS

这里通过log来查看触控笔的motionEvent&#xff0c; Overridepublic boolean onTouchEvent(MotionEvent event) {Log.i(tag, "event" event);return true;}Overridepublic boolean onGenericMotionEvent(MotionEvent event) {Log.i(tag, "G event" event…

基于CodeFormer实现图片模糊变清晰,去除马赛克等效果

前言 CodeFormer是一种基于AI技术深度学习的人脸复原模型&#xff0c;由南洋理工大学和商汤科技联合研究中心联合开发。该模型通过结合了VQGAN和Transformer等技术&#xff0c;可以通过提供模糊或马赛克图像来生成清晰的原始图像。可以实现老照片修复、照片马赛克修复、黑白照…

【ARM Coresight 系列文章 9.1 -- ITM 仪器化跟踪宏单元详细介绍】

文章目录 1.1 ITM 介绍1.1.1 ITM 功能介绍1.1.2 Cortex-M ITM 的地址范围1.2 ITM 使用1.2.1 ITM 寄存器介绍1.2.2 Cortex-M7 ITM 代码示例1.2.3 Cortex-M33 ITM 代码示例1.1 ITM 介绍 在debug 调试阶段通常都是使用 printf(printk) 来进行进行 log 输出,然后定位问题。那么如…

排序算法-希尔排序法(ShellSort)

排序算法-希尔排序法&#xff08;ShellSort&#xff09; 1、说明 我们知道当原始记录的键值大部分已排好序的情况下插入排序法非常有效&#xff0c;因为它不需要执行太多的数据搬移操作。希尔排序法是D.L.Shell在1959年7月发明的一种排序法&#xff0c;可以减少插入排序法中数…

安全论坛和外包平台汇总

文章目录 一. 网络安全论坛汇总二. 外包平台汇总1. 国内&#xff1a;2. 国外 一. 网络安全论坛汇总 安全焦点BugTraq&#xff1a;http://www.fuzzysecurity.com/Exploit-DB&#xff1a;https://www.exploit-db.com/hackone&#xff1a;https://www.hackerone.com/FreeBuf&…

保护你的爬虫免受CSRF攻击:深入了解CSRF-Token

CSRF&#xff08;Cross-Site Request Forgery&#xff09;是一种常见的网络攻击类型&#xff0c;可用于伪装用户发起的请求&#xff0c;因此保护你的爬虫免受CSRF攻击至关重要。在本文中&#xff0c;我们将深入探讨CSRF-Token&#xff0c;它在CSRF保护中的作用以及爬虫如何处理…

Java IO流

IO 即 Input / Output &#xff0c;输入输出流。IO流在Java中分为输入流和输出流&#xff0c;而根据数据的处理方式又分为字节流和字符流。 Java IO 流的 40 多个类都是从如下 4 个 抽象类基类中派生出来的。 InputStream /Reader : 所有的输入流的基类&#xff0c;前者是字节…

论文阅读之《Learn to see in the dark》

Learning to See in the Dark-CVPR2018 Chen ChenUIUC&#xff08;伊利诺伊大学厄巴纳-香槟分校&#xff09; Qifeng Chen, Jia Xu, Vladlen Koltun Intel Labs(英特尔研究院) 文章链接&#xff1a;https://arxiv.org/pdf/1805.01934.pdfhttps://arxiv.org/pdf/1805.01934.p…

rust学习Cell、RefCell、OnceCell

背景 Rust 内存安全基于以下规则:给定一个对象 T,它只能具有以下之一: 对对象有多个不可变引用 (&T)(也称为别名 aliasing)对对象有一个可变引用 (&mut T)(也称为可变性 mutability)这是由 Rust 编译器强制执行的。然而,在某些情况下,该规则不够灵活(this r…

Android Studio展示Activty生命周期

前言 本文章以及之后文章的程序版本使用Android Studio 2022.3.1 Patch 1 版本编辑&#xff0c;使用语言为java&#xff0c;最低支持API 27 Android 8.1&#xff0c;构建工具版本如下&#xff1a; 本文章主要是介绍Activty跳转和删除&#xff0c;以备后续使用&#xff0c;所以就…

pxb 使用物理备份恢复数据库

开源软件 Percona Xtrabackup 可以用于对数据库进行备份恢复&#xff0c;本文为您介绍使用 XtraBackup 工具&#xff0c;将 MySQL 物理备份文件恢复至其他主机上的自建数据库。 注意 如果使用透明加密或 Instant DDL 功能&#xff0c;则无法使用物理备份在自建系统上进行恢复…

sql 注入(4), 盲注

sql 注入, 盲注 盲注适合在页面没有任何回显时使用. 测试页面有变化, 但是没有显示任何异常错误等信息. 情景: url: http://192.168.112.200/security/read.php?id1 服务器数据库名: learn一, boolean盲注 # 盲注可能需要一个一个字符去试探, 字符串处理函数经常会用到. 比…

命令行启动android模拟器

有时候不想打开android studio就能方便的启动模拟器&#xff0c;探索一番后发现可以通过命令行来启动&#xff0c;方便快捷。 环境准备 首先安装好android studio&#xff0c;android sdk&#xff0c;从android studio中安装好模拟器。 命令启动 如果直接在终端输入emulato…

计算机的字符与编码集

文章目录 前言一、字符编码集的历史1.ASCII码2.Extended ASCII码3.字符编码集的国际化 二、中文编码集 前言 今天给大家介绍计算机的字符与编码集&#xff0c;分为两部分&#xff1a;字符编码集的历史、中文编码集。 一、字符编码集的历史 这部分包含三个板块内容&#xff1a…

【通信系列 5 -- HTTPS 介绍】

文章目录 1.1 HTTPS链接网址1.1.1 HTTPS 产生背景1.1.2 HTTPS工作内容1.1.3 SSL/TLS1.1.4 TLS 的命名规范1.1.5 TLS 加密算法1.1.6 分组模式1.1.7 摘要算法1.1.8 非对称加密1.1.9 CA认证 1.2 openssl1.2.1 RSA 签名验签 1.1 HTTPS链接网址 HTTP 是一种 超文本传输协议(Hyperte…

DOCKER本地仓库

概述 随着docker的应用越来越多&#xff0c;安装部署越来越方便&#xff0c;批量自动化的镜像生成和发布都需要docker仓库的本地化应用。 试用了docker的本地仓库功能&#xff0c;简单易上手&#xff0c;记录下来以备后用。 环境 centos&#xff1a;CentOS release 7.0 (F…

CANoe创建仿真工程

CANoe创建仿真工程 写在前面仿真工程的创建创建工程添加CAN数据库添加系统变量创建面板创建网络节点为节点添加代码工程运行测试总结 写在前面 Canoe的安装不是特别方便&#xff0c;我是参加了松勤的培训课程&#xff0c;不仅需要安装软件还需要安装驱动&#xff0c;刚刚学习的…

[程序人生]常用的Linux命令简称与全称

常用的Linux命令简称与全称 引言 学习Linux系统操作的时候&#xff0c;那些命令很难记&#xff0c;让人头大。 本文给出Linux系统中常用的命令简称与全称。 正文 以下是常用的Linux命令简称与全称&#xff1a; pwd (print working directory)&#xff1a;显示当前工作目录的…

【PWN · 栈迁移】[CISCN 2019东南]PWN2

一道非常典型、适合用作学习栈迁移的题目。 前言 当存在栈溢出但是溢出字符数并不多的情况下&#xff0c;可以尝试在别处构造rop链&#xff0c;通过栈迁移到目标内存区域&#xff0c;执行rop链。这里不讲栈迁移原理&#xff0c;仅是对题目的分析&#xff0c;适合对栈迁移有初步…

【stm32】外部中断接口函数

1、外部中断回调函数 2、外部中断通用处理函数