当前位置: 首页 > news >正文

条款47:请使用 traits classes 表现类型信息(Use traits classes for information about types)

条款47:请使用 traits classes 表现类型信息

1.1 提出问题

想一想,下面的功能如何实现?(可以查看std::advance源码)

template<typename IterT, typename DistT>  
void advance(IterT& iter, DistT d); //前进iter d个单位;如果d<0,将iter向后移动 

迭代器有很多类型,所以实现并不是iter+=d这么简单,需要考虑不同的迭代器类型。

struct input_iterator_tag {};
struct output_iterator_tag {};
struct forward_iterator_tag : public input_iterator_tag {};
struct bidirectional_iterator_tag : public forward_iterator_tag {};
struct random_access_iterator_tag : public bidirectional_iterator_tag {};template<typename IterT, typename DistT>
void advance(IterT& iter, DistT d)
{
//我们需要获取类型的信息,以选择最快的方式
//这就是traits的作用:它们允许你在编译期间获取有关类型的信息。if (iter 是随机访问迭代器) {iter += d;  }  else {if (d >= 0) { while (d--) ++iter; }  else { while (d++) --iter; }  } 
}

1.2 解决办法

trait不是C++中的关键字或预定义结构;它们是C++程序员遵循的一种技术和约定。对该技术的要求之一是,它必须像对自定义类型一样对待内置类型。意味着在类型中嵌套信息之类的无法实现,因为没有办法在指针内部嵌套信息。因此,类型的traits信息必须位于类型的外部。

template<typename IterT> 
struct iterator_traits; // 关于迭代器类型信息的模板//deque迭代器的类如下所示:
template < ... > // 模板参数被省略
class deque {
public:class iterator {public:     
//任何自定义的迭代器类型都必须包含一个嵌套的名为iterator_category的typedef,用于确认迭代器的分类。typedef random_access_iterator_tag iterator_category;...} :...
};

Iterator_traits只是鹦鹉学舌地响应了iterator类的嵌套typedef:

// IterT类型的iterator_category是IterT指定的类型
template<typename IterT>
struct iterator_traits {typedef typename IterT::iterator_category iterator_category;...
};
//这对于自定义类型很有效,但对于指针类型的迭代器根本不起作用,因为不存在具有嵌套typedef的指针。

iterator_traits为指针类型提供了模板的偏特化。指针充当随机访问迭代器,因此iterator_traits为它们指定了类别:

template<typename IterT> 	 
struct iterator_traits<IterT*> // 内置指针类型的模板偏特化
{typedef random_access_iterator_tag iterator_category;...
};

有了iterator_traits,(实际上它是标准库的一部分)我们可以改进advance的伪代码:

template<typename IterT, typename DistT>
void advance(IterT& iter, DistT d)
{
//typeid运行时获知变量类型名称if (typeid(typename std::iterator_traits<IterT>::iterator_category) ==typeid(std::random_access_iterator_tag))...
}
//在 C++17 之后,可以使用if constexpr:
//if 语句将在运行时期进行判断

我们可以通过重载,在编译期进行判断:

template<typename IterT, typename DistT> // 用于随机访问迭代器
void doAdvance(IterT& iter, DistT d, std::random_access_iterator_tag)  
{iter += d;
}
template<typename IterT, typename DistT> // 用于双向迭代器
void doAdvance(IterT& iter, DistT d, std::bidirectional_iterator_tag) 
{if (d >= 0) { while (d--) ++iter; }else { while (d++) --iter; }
}
template<typename IterT, typename DistT> // 用于输入迭代器
void doAdvance(IterT& iter, DistT d, std::input_iterator_tag)
{if (d < 0) {throw std::out_of_range("Negative distance"); }while (d--) ++iter;
}
template<typename IterT, typename DistT>
void advance(IterT& iter, DistT d)
{doAdvance(iter, d, typename std::iterator_traits<IterT>::iterator_category()); 
} 

1.3 总结

  1. traits类提供编译期间可用的类型信息。它们是使用模板和模板特化实现的。
  2. 与重载相结合,traits类可以在编译时执行“if……else”对类型进行测试。

相关文章:

条款47:请使用 traits classes 表现类型信息(Use traits classes for information about types)

条款47&#xff1a;请使用 traits classes 表现类型信息 1.1 提出问题 想一想&#xff0c;下面的功能如何实现&#xff1f;&#xff08;可以查看std::advance源码&#xff09; template<typename IterT, typename DistT> void advance(IterT& iter, DistT d); /…...

yolov5和yolov8的区别

1. yolov5有建议框&#xff0c;yolov8没有建议框 2. yolov5标签中有自信度&#xff0c;而yolov8没有自信度。因为自信度是建议框和真实框的交集 3. yolov5有三个损失函数&#xff0c;回归问题&#xff1a;预测框和建议框的损失(中心点宽高偏移量的损失)&#xff1a;CIOUFocal…...

Redis 实现分布式锁

文章目录 引言一、Redis的两种原子操作1.1 Redis 的原子性1.2 单命令1.3 Lua 脚本1.4 对比单命令与 Lua 脚本 二、Redis 实现分布式锁2.1 分布式锁的概念与需求2.1.1 什么是分布式锁&#xff1f;2.1.2 分布式锁的常见应用场景 2.2 基于 Redis 的分布式锁实现2.2.1 锁的获取与释…...

django StreamingHttpResponse fetchEventSource实现前后端流试返回数据并接收数据的完整详细过程

django后端环境介绍&#xff1a; Python 3.10.14 pip install django-cors-headers4.4.0 Django5.0.6 django-cors-headers4.4.0 djangorestframework3.15.2 -i https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple 总环境如下&#xff1a; Package Version -…...

SpringSpringBoot常用注解总结

目录 1. SpringBootApplication 2. Spring Bean 相关 2.1. Autowired 2.2. Component,Repository,Service, Controller 2.3. RestController 2.4. Scope 2.5. Configuration 3. 处理常见的 HTTP 请求类型 3.1. GET 请求 3.2. POST 请求 3.3. PUT 请求 3.4. DELETE 请…...

24.小R的随机播放顺序<字节青训营-中等题>

1.题目 问题描述 小R有一个特殊的随机播放规则。他首先播放歌单中的第一首歌&#xff0c;播放后将其从歌单中移除。如果歌单中还有歌曲&#xff0c;则会将当前第一首歌移到最后一首。这个过程会一直重复&#xff0c;直到歌单中没有任何歌曲。 例如&#xff0c;给定歌单 [5, …...

【QT】增删改查 XML 文件的类

使用单例类模板实现的对XML文件的节点、属性、文本进行增删改查,可以直接用! 直接POST代码,比较简单好用。 针对以下格式的xml文件比较适用 每个节点的名称都不一样,节点包含了各种属性。 <?xml version="1.0" encoding="UTF-8"?> <config…...

Linux-掉电保护方案

参考链接 https://blog.csdn.net/pwl999/article/details/109411919硬件设计 设备树 驱动程序 #include <linux/module.h> #include <linux/init.h> #include <linux/interrupt.h> #include <linux/gpio.h>int irq;//中断服务函数 irqreturn_t tes…...

php获取字符串中的汉字

在PHP中&#xff0c;可以使用正则表达式来提取字符串中的汉字。汉字通常位于Unicode范围\u4e00-\u9fa5之内&#xff0c;因此可以使用preg_match_all函数配合适当的正则表达式来实现。 以下是一个PHP代码示例&#xff0c;它会从给定的字符串中提取出所有的汉字&#xff1a; fu…...

java: JDK isn‘t specified for module ‘product-service‘问题解决

目录 问题 解决方法 1.打开File->Project Structure... 2.将Project SDK修改为17 Oracle OpenJDK 17.0.12&#xff0c;并Apply&#xff0c;OK 问题 添加module后报错&#xff1a;java: JDK isnt specified for module product-service 查看pom.xml文件也添加了对应的JDK…...

使用工厂+策略模式实现去除繁琐的if else

使用工厂策略模式实现去除繁琐的if else 在中间有一个mapstruct的bug&#xff0c;即在修改实体类中的类型时&#xff0c;或者修改属性名字&#xff0c;mapstruct都无法进行转换&#xff0c;会报错&#xff0c;此时需要maven cleanmaven compile即可 前言 在这次的开发中&#…...

Dubbo3入门项目搭建

开发环境&#xff1a;jdk8、dubbo3.2.9、nacos2.3.0、springboot2.7.17、dubbo-admin0.6.0。 Dubbo 是一个高性能的 Java RPC&#xff08;远程调用&#xff09;框架&#xff0c;最初由阿里巴巴开发并开源&#xff0c;主要用于构建 SOA 架构下的分布式应用系统( soa简单理解就是…...

形象地理解UE4中的数据结构 TLinkedListBase

大家都熟知链表&#xff0c;但不一定能快速看懂UE4中的数据结构。 TLinkedListBase表示“链接”中的一个结点&#xff0c;有三个成员&#xff1a; 一、ElementType Element; 表示具体的业务&#xff0c;例如int链条中的一个整数。 二、NextLink 表示 “下一个Node”&#…...

Python自然语言处理利器:SnowNLP模块深度解析、安装指南与实战案例

Python自然语言处理之SnowNLP模块介绍、安装与常见操作案例 一、SnowNLP模块介绍 SnowNLP是一个专为中文文本设计的Python库&#xff0c;它基于自然语言处理技术&#xff0c;提供了多种功能&#xff0c;包括分词、词性标注、情感分析、文本转换&#xff08;简繁转换&#xff…...

Llama系列关键知识总结

系列文章目录 第一章&#xff1a;LoRA微调系列笔记 第二章&#xff1a;Llama系列关键知识总结 第三章&#xff1a;LLaVA模型讲解与总结 文章目录 系列文章目录Llama: Open and Efficient Foundation Language Models关键要点LLaMa模型架构&#xff1a;Llama2分组查询注意力 (G…...

【开源】创建自动签到系统—QD框架

1. 介绍 QD是一个 基于 HAR 编辑器和 Tornado 服务端的 HTTP 定时任务自动执行 Web 框架。 主要通过抓包获取到HAR来制作任务模板&#xff0c;从而实现异步响应和发起HTTP请求 2. 需要环境 2.1 硬件需求 CPU&#xff1a;至少1核 内存&#xff1a;推荐 ≥ 1G 硬盘&#xff1a;推…...

​​​​​​​CDP集群安全指南系列文章导读

[一]大数据安全综述 1-认证 身份验证是任何计算环境的基本安全要求。简单来说&#xff0c;用户和服务必须在使用系统功能并获得授权之前&#xff0c;向系统证明其身份&#xff08;进行身份验证&#xff09;。身份验证与授权紧密配合&#xff0c;共同保护系统资源。大多数 CDH …...

MT8788安卓核心板_MTK8788核心板参数_联发科模块定制开发

MT8788安卓核心板是一款尺寸为52.5mm x 38.5mm x 2.95mm的高集成度电路板&#xff0c;专为各种智能设备应用而设计。该板卡整合了处理器、图形处理单元(GPU)、LPDDR3内存、eMMC存储及电源管理模块&#xff0c;具备出色的性能与低功耗特性。 这款核心板搭载了联发科的MT8788处理…...

【微软,模型规模】模型参数规模泄露:理解大型语言模型的参数量级

模型参数规模泄露&#xff1a;理解大型语言模型的参数量级 关键词&#xff1a; #大型语言模型 Large Language Model #参数规模 Parameter Scale #GPT-4o #GPT-4o-mini #Claude 3.5 Sonnet 具体实例与推演 近日&#xff0c;微软在一篇医学相关论文中意外泄露了OpenAI及Claud…...

深入理解并发原子性、可见性、有序性与JMM内存模型

1. 并发三大特性 并发编程Bug的源头&#xff1a;原子性、可见性和有序性问题 1.1 原子性 一个或多个操作&#xff0c;要么全部执行且在执行过程中不被任何因素打断&#xff0c;要么全部不执行。在 Java 中&#xff0c;对基本数据类型的变量的读取和赋值操作是原子性操作&…...

IPD的势、道、法、术、器

目录 简介 一、势&#xff1a;为什么 IPD 是必然选择&#xff1f; 二、道&#xff1a;IPD 的底层哲学 三、法与术&#xff1a;从战略到执行的具体路径 四、器&#xff1a;让流程真正落地的工具与组织 不是每家公司都需要全套 IPD&#xff0c;但每家公司都需要 IPD 思维 简…...

电容损坏深度诊断,从外观到 ESR精准区分容衰与漏电

在 PCB 故障中&#xff0c;电容损坏占比超 40%&#xff0c;是当之无愧的 “头号杀手”。很多工程师仅靠 “鼓包漏液” 判断电容好坏&#xff0c;殊不知80% 的电容损坏是隐性的—— 外观平整但容值衰减、ESR 升高、轻微漏电&#xff0c;导致供电不稳、系统重启、噪声增大&#x…...

SMUDebugTool终极指南:如何深度掌控AMD Ryzen处理器的隐藏性能

SMUDebugTool终极指南&#xff1a;如何深度掌控AMD Ryzen处理器的隐藏性能 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table. 项目地址: ht…...

科华UPS电源全品类汇总:选型与场景适配指南

科华UPS电源作为国内智慧电能领域的主流产品&#xff0c;覆盖家用、办公、机房、工业等全场景&#xff0c;产品系列丰富、规格齐全&#xff0c;但多数用户在选型时&#xff0c;常因分不清系列差异、功率适配、架构类型而踩坑。本文系统汇总科华UPS电源的核心分类、主流系列、核…...

从“DOC/PDF”到“WPS”:细看GJB438C-2021文档格式要求背后的国产化信号与落地指南

从“DOC/PDF”到“WPS”&#xff1a;GJB438C-2021文档格式变革的深度解读与实施策略 当一份国家军用标准在文档格式描述中刻意删除"DOC/PDF"字样&#xff0c;转而明确标注"&#xff08;WPS&#xff09;文档处理器"时&#xff0c;这绝非简单的技术参数调整。…...

量子纠错码VarQEC:原理、实现与硬件优化

1. 量子纠错码基础与实验背景量子纠错码&#xff08;Quantum Error Correction Codes, QEC&#xff09;是量子计算中保护量子信息免受噪声影响的核心技术。与经典纠错码不同&#xff0c;量子纠错需要应对量子态特有的退相干和纠缠特性。传统QEC如[[5,1,3]]完美码虽然理论完备&a…...

LDBlockShow实战指南:基因组连锁不平衡分析与可视化解决方案

LDBlockShow实战指南&#xff1a;基因组连锁不平衡分析与可视化解决方案 【免费下载链接】LDBlockShow LDBlockShow: a fast and convenient tool for visualizing linkage disequilibrium and haplotype blocks based on VCF files 项目地址: https://gitcode.com/gh_mirror…...

Unity新手避坑指南:NavMesh烘焙参数(Agent Radius/Height)到底怎么设?附场景实测

Unity导航系统深度解析&#xff1a;Agent参数设置与场景适配实战在Unity游戏开发中&#xff0c;导航系统(Navigation System)是实现角色智能移动的核心模块。对于刚接触Unity导航系统的开发者来说&#xff0c;Agent Radius(代理半径)和Agent Height(代理身高)这两个参数的设置往…...

从SIM800到BK A7670E:4G Cat.1模块硬件平替转接板设计全解析

1. 项目概述&#xff1a;从2G到4G的硬件平替升级 手头有个老项目&#xff0c;用的还是SIM800这种经典的2G模块&#xff0c;现在网络环境变了&#xff0c;2G退网是大势所趋&#xff0c;信号覆盖越来越差&#xff0c;项目得活下去&#xff0c;升级到4G成了刚需。但问题来了&#…...

安卓用户如何免费获取大模型API密钥并开始调用

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 安卓用户如何免费获取大模型API密钥并开始调用 对于安卓开发者或移动端技术爱好者而言&#xff0c;直接体验和调用多种大模型的能力…...