条款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 总结
- traits类提供编译期间可用的类型信息。它们是使用模板和模板特化实现的。
- 与重载相结合,traits类可以在编译时执行“if……else”对类型进行测试。
相关文章:
条款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); /…...
yolov5和yolov8的区别
1. yolov5有建议框,yolov8没有建议框 2. yolov5标签中有自信度,而yolov8没有自信度。因为自信度是建议框和真实框的交集 3. yolov5有三个损失函数,回归问题:预测框和建议框的损失(中心点宽高偏移量的损失):CIOUFocal…...
Redis 实现分布式锁
文章目录 引言一、Redis的两种原子操作1.1 Redis 的原子性1.2 单命令1.3 Lua 脚本1.4 对比单命令与 Lua 脚本 二、Redis 实现分布式锁2.1 分布式锁的概念与需求2.1.1 什么是分布式锁?2.1.2 分布式锁的常见应用场景 2.2 基于 Redis 的分布式锁实现2.2.1 锁的获取与释…...
django StreamingHttpResponse fetchEventSource实现前后端流试返回数据并接收数据的完整详细过程
django后端环境介绍: 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 总环境如下: 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有一个特殊的随机播放规则。他首先播放歌单中的第一首歌,播放后将其从歌单中移除。如果歌单中还有歌曲,则会将当前第一首歌移到最后一首。这个过程会一直重复,直到歌单中没有任何歌曲。 例如,给定歌单 [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中,可以使用正则表达式来提取字符串中的汉字。汉字通常位于Unicode范围\u4e00-\u9fa5之内,因此可以使用preg_match_all函数配合适当的正则表达式来实现。 以下是一个PHP代码示例,它会从给定的字符串中提取出所有的汉字: fu…...
java: JDK isn‘t specified for module ‘product-service‘问题解决
目录 问题 解决方法 1.打开File->Project Structure... 2.将Project SDK修改为17 Oracle OpenJDK 17.0.12,并Apply,OK 问题 添加module后报错:java: JDK isnt specified for module product-service 查看pom.xml文件也添加了对应的JDK…...
使用工厂+策略模式实现去除繁琐的if else
使用工厂策略模式实现去除繁琐的if else 在中间有一个mapstruct的bug,即在修改实体类中的类型时,或者修改属性名字,mapstruct都无法进行转换,会报错,此时需要maven cleanmaven compile即可 前言 在这次的开发中&#…...
Dubbo3入门项目搭建
开发环境:jdk8、dubbo3.2.9、nacos2.3.0、springboot2.7.17、dubbo-admin0.6.0。 Dubbo 是一个高性能的 Java RPC(远程调用)框架,最初由阿里巴巴开发并开源,主要用于构建 SOA 架构下的分布式应用系统( soa简单理解就是…...
形象地理解UE4中的数据结构 TLinkedListBase
大家都熟知链表,但不一定能快速看懂UE4中的数据结构。 TLinkedListBase表示“链接”中的一个结点,有三个成员: 一、ElementType Element; 表示具体的业务,例如int链条中的一个整数。 二、NextLink 表示 “下一个Node”&#…...
Python自然语言处理利器:SnowNLP模块深度解析、安装指南与实战案例
Python自然语言处理之SnowNLP模块介绍、安装与常见操作案例 一、SnowNLP模块介绍 SnowNLP是一个专为中文文本设计的Python库,它基于自然语言处理技术,提供了多种功能,包括分词、词性标注、情感分析、文本转换(简繁转换ÿ…...
Llama系列关键知识总结
系列文章目录 第一章:LoRA微调系列笔记 第二章:Llama系列关键知识总结 第三章:LLaVA模型讲解与总结 文章目录 系列文章目录Llama: Open and Efficient Foundation Language Models关键要点LLaMa模型架构:Llama2分组查询注意力 (G…...
【开源】创建自动签到系统—QD框架
1. 介绍 QD是一个 基于 HAR 编辑器和 Tornado 服务端的 HTTP 定时任务自动执行 Web 框架。 主要通过抓包获取到HAR来制作任务模板,从而实现异步响应和发起HTTP请求 2. 需要环境 2.1 硬件需求 CPU:至少1核 内存:推荐 ≥ 1G 硬盘:推…...
CDP集群安全指南系列文章导读
[一]大数据安全综述 1-认证 身份验证是任何计算环境的基本安全要求。简单来说,用户和服务必须在使用系统功能并获得授权之前,向系统证明其身份(进行身份验证)。身份验证与授权紧密配合,共同保护系统资源。大多数 CDH …...
MT8788安卓核心板_MTK8788核心板参数_联发科模块定制开发
MT8788安卓核心板是一款尺寸为52.5mm x 38.5mm x 2.95mm的高集成度电路板,专为各种智能设备应用而设计。该板卡整合了处理器、图形处理单元(GPU)、LPDDR3内存、eMMC存储及电源管理模块,具备出色的性能与低功耗特性。 这款核心板搭载了联发科的MT8788处理…...
【微软,模型规模】模型参数规模泄露:理解大型语言模型的参数量级
模型参数规模泄露:理解大型语言模型的参数量级 关键词: #大型语言模型 Large Language Model #参数规模 Parameter Scale #GPT-4o #GPT-4o-mini #Claude 3.5 Sonnet 具体实例与推演 近日,微软在一篇医学相关论文中意外泄露了OpenAI及Claud…...
深入理解并发原子性、可见性、有序性与JMM内存模型
1. 并发三大特性 并发编程Bug的源头:原子性、可见性和有序性问题 1.1 原子性 一个或多个操作,要么全部执行且在执行过程中不被任何因素打断,要么全部不执行。在 Java 中,对基本数据类型的变量的读取和赋值操作是原子性操作&…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...
利用最小二乘法找圆心和半径
#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...
观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...
Java如何权衡是使用无序的数组还是有序的数组
在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...
HBuilderX安装(uni-app和小程序开发)
下载HBuilderX 访问官方网站:https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本: Windows版(推荐下载标准版) Windows系统安装步骤 运行安装程序: 双击下载的.exe安装文件 如果出现安全提示&…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...
九天毕昇深度学习平台 | 如何安装库?
pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子: 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...
基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...
永磁同步电机无速度算法--基于卡尔曼滤波器的滑模观测器
一、原理介绍 传统滑模观测器采用如下结构: 传统SMO中LPF会带来相位延迟和幅值衰减,并且需要额外的相位补偿。 采用扩展卡尔曼滤波器代替常用低通滤波器(LPF),可以去除高次谐波,并且不用相位补偿就可以获得一个误差较小的转子位…...
