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

奇异递归Template有啥奇的?

如果一个模版看起来很头痛,那么大概率这种模版是用来炫技,没啥用的,但是CRTP这个模版,虽然看起来头大,但是却经常被端上桌~

奇异递归模板模式(Curiously Recurring Template Pattern, CRTP)是一种 C++ 模板编程技巧,用于实现静态多态。这种模式利用模板递归来允许一个类继承自一个模板类,其中模板参数是该类自身。这种模式可以用于各种用途,包括实现类型安全的单例模式、静态接口和性能优化。

CRTP基本概念

在 CRTP 模式中,一个类 Derived 继承自一个模板类 Base,这个模板类 Base 的模板参数是 Derived 自身。这样做的好处是允许在编译时确定 Derived 类型的信息,从而在不需要运行时多态的情况下实现多态行为。以下是 CRTP 的基本示例,展示了如何使用 CRTP 模式实现一个简单的静态接口:

#include <iostream>
using namespace std;template <typename Child>
struct Base
{
void interface()
{static_cast<Child*>(this)->implementation();
}
};struct Derived : Base<Derived>
{
void implementation()
{cout << "Derived implementation\n";
}
};int main()
{Derived d;d.interface();  // Prints "Derived implementation"return 0;
}

CRPT模板展开

遇到CRPT不要慌,一慌忘光光,为了认识这种代码的本质,我们不妨用Insights将其展开 , C++ Insights

#include <iostream>
using namespace std;template<typename Child>
struct Base
{inline void interface(){static_cast<Child *>(this)->implementation();}};/* First instantiated from: insights.cpp:13 */
#ifdef INSIGHTS_USE_TEMPLATE
template<>
struct Base<Derived>
{inline void interface(){static_cast<Derived *>(this)->implementation();}// inline constexpr Base() noexcept = default;
};#endifstruct Derived : public Base<Derived>
{inline void implementation(){std::operator<<(std::cerr, "Derived implementation\n");}// inline constexpr Derived() noexcept = default;
};int main()
{Derived d;static_cast<Base<Derived>&>(d).interface();return 0;
}

可以发现,展开的代码平平无奇,一目了然。

  • Base 类是一个模板类,它接受一个 Derived 类型作为模板参数。
  • Derived 类继承自 Base<Derived>,从而在 Base 中能够静态地调用 Derived 类中的方法。

另一个CRPT实例

以下是一个稍微复杂一点使用 CRTP 实现策略模式的例子:


#include <iostream>// CRTP 基类
template <typename Derived>
class Strategy {
public:
void execute() {// 调用 Derived 类中的实现static_cast<Derived*>(this)->perform();
}
};// 具体策略 1
class ConcreteStrategy1 : public Strategy<ConcreteStrategy1> {
public:
void perform() {std::cout << "ConcreteStrategy1 implementation" << std::endl;
}
};// 具体策略 2
class ConcreteStrategy2 : public Strategy<ConcreteStrategy2> {
public:
void perform() {std::cout << "ConcreteStrategy2 implementation" << std::endl;
}
};int main() {ConcreteStrategy1 s1;ConcreteStrategy2 s2;s1.execute(); // 输出 "ConcreteStrategy1 implementation"s2.execute(); // 输出 "ConcreteStrategy2 implementation"return 0;
}

在这个示例中,Strategy 是 CRTP 基类,它定义了一个 execute 方法,该方法调用派生类的 perform 方法。具体策略类 ConcreteStrategy1ConcreteStrategy2 实现了不同的 perform 方法。这样,Strategy 基类就能够静态地调用不同的策略实现。

总结

看到CRPT,第一眼应该想到,这玩意没什么特别的,就是为了实现静态多态的。

  • 静态体现在哪儿,都是模版函数,在编译期都已经展开,函数调用是写死的
  • 多态体现在哪儿,调佣基类的公用接口,最后会执行子类的具体实现,这一点和虚函数多态有点相似,但这种多态是静态的。

所以,CRPT就这点东西。

相关文章:

奇异递归Template有啥奇的?

如果一个模版看起来很头痛&#xff0c;那么大概率这种模版是用来炫技&#xff0c;没啥用的&#xff0c;但是CRTP这个模版&#xff0c;虽然看起来头大&#xff0c;但是却经常被端上桌~ 奇异递归模板模式&#xff08;Curiously Recurring Template Pattern, CRTP&#xff09;是一…...

每天五分钟深度学习框架pytorch:神经网络工具箱nn的介绍

本文重点 我们前面一章学习了自动求导,这很有用,但是在实际使用中我们基本不会使用,因为这个技术过于底层,我们接下来将学习pytorch中的nn模块,它是构建于autograd之上的神经网络模块,也就是说我们使用pytorch封装好的神经网络层,它自动会具有求导的功能,也就是说这部…...

【办公软件】安全风险 Microsoft 已阻止宏运行,因为此文件的来源不受信任

Excel 2019版本&#xff0c;就出现安全风险 Microsoft 已阻止宏运行 因为此文件的来源不受信任的问题&#xff0c;宏直接就用不了了。 网上的解决方法&#xff0c;文件右键属性->取消安全锁。但存在没有安全锁这个选项。后查询到一个简单的解决方法。 打开Excel表格->文件…...

JavaScript语法基础之流程结构(顺序、选择、循环结构)

目录 1. 流程控制 1.1. 流程控制简介 1.1.1. 顺序结构 1.1.2. 选择结构 1.1.3. 循环结构 1.2. 选择结构&#xff1a;if 1.2.1. 单向选择&#xff1a;if… 1.2.2. 双向选择&#xff1a;if…else… 1.2.3. 多向选择&#xff1a;if…else_if…else… 1.3. 选择结构&#…...

集团数字化转型方案(四)

集团数字化转型方案通过全面部署人工智能&#xff08;AI&#xff09;、大数据分析、云计算和物联网&#xff08;IoT&#xff09;技术&#xff0c;创建了一个智能化的企业运营平台&#xff0c;涵盖从业务流程自动化、实时数据监控、精准决策支持&#xff0c;到个性化客户服务和高…...

【MySQL索引】索引失效场景

索引失效 1 全值匹配肯定不失效 2 最佳左前缀法则 索引文件具有 B-Tree 的最左前缀匹配特性&#xff0c;如果左边的值未确定&#xff0c;那么无法使用此索引。 3 主键插入顺序 页分裂&#xff0c;建议 让主键具有 AUTO_INCREMENT 4 计算、函数、类型转换(自动或手动)导致…...

基于MATLAB视觉的静态手势识别系统

一、课题介绍及思路 为了丰富手势识别方法的多样性&#xff0c;提高手势识别的正确率&#xff0c;提出了一种基于手势轮廓像素变化的手势识别方法。在Matlab环境下&#xff0c;设计并开发了一个基于视觉的静态手势识别系统。系统主要由两部分组成&#xff1a;手势分割与手势识…...

day02-作业题

一、简答题 请说出方法定义的全格式 访问修饰符 静态修饰符 返回值 方法名(参数列表){方法体;retrun 返回值;}请说出方法重载的概念 在一个类中&#xff0c;可以定义方法名相同&#xff0c;参数列表不相同(参数类型、参数个数或者参数顺序不同)的方法请简述什么是类&#xf…...

torch.cuda.set_divice()

我申请了两块GPU,然后看两张显卡的编号 import torch torch.cuda.set_device(0) # 设置当前cuda设备编号为1 print("当前cuda设备是", torch.cuda.current_device()) # 获取当前cuda设备import torch torch.cuda.set_device(1) …...

<数据集>RSOD数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;936张 标注数量(xml文件个数)&#xff1a;936 标注数量(txt文件个数)&#xff1a;936 标注类别数&#xff1a;4 标注类别名称&#xff1a;[aircraft, oiltank, overpass, playground] 序号类别名称图片数框数1air…...

企业高性能web服务器之Nginx

文章目录 Apache经典的web服务端Apache prefork 模型Apache work 模型&#xff08;适应市场&#xff09;Apache event 模型 网络I/O网络I/O模型I/O模型网络I/O模型 Nginx架构和安装Nginx源码编译环境准备安装nginx Nginx的平滑升级及版本回滚 Nginx架构和进程Nginx进程结构Ngin…...

11-sentinel利用nacos作持久化

本文介绍sentinel配置数据的持久化方法。由于sentinel官方并没有提供持久化功能&#xff0c;大家在测试过程中也能发现sentinel服务重启后&#xff0c;原来配置的数据就丢了&#xff0c;本文就是来处理这一问题的。 做好心理准备&#xff0c;我们要修改sentinel的源代码&#…...

密码学之哈希算法

文章目录 1. 哈希函数概述1.1 哈希函数的定义1.2 哈希函数的重要性 2. SHA系列算法简介2.1 SHA系列的发展历史2.2 SHA系列的应用场景 3. 主要SHA算法详解3.1 MD5算法3.2 SHA-1算法3.3 SHA-2算法家族3.4 SHA-3算法 4. SHA算法的安全性分析4.1 安全性的重要性4.2 已知的攻击方法4…...

杰发科技AC7801——GPIO通过寄存器地址控制高低电平

通过这个寄存器来查看控制的是哪个ODR值&#xff0c;使用sample&#xff0c;发现是0x20080068的第7和第9位 使用51控制寄存器的代码来置高置低代码&#xff0c;注意变量需要用unsigned int来声明 unsigned int ledBit 0;mdelay(100);ledBit | (1 << 9); ledBit & ~…...

代码随想录算法训练营第三十一天| 01背包问题 二维 01背包问题 一维 416. 分割等和子集

01背包问题 二维 代码随想录 视频讲解&#xff1a;带你学透0-1背包问题&#xff01;| 关于背包问题&#xff0c;你不清楚的地方&#xff0c;这里都讲了&#xff01;| 动态规划经典问题 | 数据结构与算法_哔哩哔哩_bilibili #include <bits/stdc.h> using namespace std;…...

github删除历史所有commit

背景 注意非确认情况下最好不要此操作 由于不小心在某些commits中提交了敏感信息&#xff0c;需要删除这些commits记录 网上看了很多方法&#xff0c;都是根据commit 找到一条id然后全部清除得&#xff0c;因为我是需要全部删除&#xff0c;所以有一种更简单得思路。 过程 1…...

C++前向声明简介

前向声明 class a; class b; class c:public d { ..... }类a和b已经实现了具体功能&#xff0c;类c在定义&#xff0c;在类c上面声明类a和b有什么作用 在类 c 的定义上面声明类 a 和 b 的作用主要是为了确保在编译时能够识别这两个类的存在&#xff0c;特别是在类 c 中可能会使…...

华为手机是越贵越好吗?

华为手机的价格与其性能、功能、设计以及市场定位等多种因素有关&#xff0c;因此不能简单地说华为手机越贵就越好。 首先&#xff0c;华为手机的产品线非常广泛&#xff0c;涵盖了从入门级到旗舰级的多个系列&#xff0c;每个系列都有其特定的目标用户群和市场需求。因此&…...

【java基础】IDEA 的断点调试(Debug)

目录 1.为什么需要 Debug 2.Debug的步骤 2.1添加断点 2.2单步调试工具介绍 2.2.1 Step Over 2.2.2 Step Into 2.2.3 Force Step Into 2.2.4 Step Out 2.2.5 Run To Cursor 2.2.6 Show Execution Poiint 2.2.7 Resume Program 3.多种 Debug 情况介绍 3.1行断点 3.2方…...

MPLS相关实验

一、实验拓扑图以及实验要求 1、实验拓扑图 2、实验要求 合理利用IP地址进行分配R3、R4、R5、R6运行ospf在R2、R3、R4、R5、R6上运行MPLSR1上使用静态&#xff0c;R7上运行rip协议&#xff0c;R8上运行ospf协议全网可达 二、实验分析 合理利用IP地址进行分配R3、R4、R5、R6…...

JavaSec-RCE

简介 RCE(Remote Code Execution)&#xff0c;可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景&#xff1a;Groovy代码注入 Groovy是一种基于JVM的动态语言&#xff0c;语法简洁&#xff0c;支持闭包、动态类型和Java互操作性&#xff0c…...

简易版抽奖活动的设计技术方案

1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统

医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上&#xff0c;开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识&#xff0c;在 vs 2017 平台上&#xff0c;进行 ASP.NET 应用程序和简易网站的开发&#xff1b;初步熟悉开发一…...

Python:操作 Excel 折叠

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验

一、多模态商品数据接口的技术架构 &#xff08;一&#xff09;多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如&#xff0c;当用户上传一张“蓝色连衣裙”的图片时&#xff0c;接口可自动提取图像中的颜色&#xff08;RGB值&…...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成&#xff0c;核心是利用 HTTP 协议的 Range 请求头指定下载范围&#xff1a; 实现原理 Range 请求头&#xff1a;向服务器请求文件的特定字节范围&#xff08;如 Range: bytes1024-&#xff09; 本地文件记录&#xff1a;保存已…...

【2025年】解决Burpsuite抓不到https包的问题

环境&#xff1a;windows11 burpsuite:2025.5 在抓取https网站时&#xff0c;burpsuite抓取不到https数据包&#xff0c;只显示&#xff1a; 解决该问题只需如下三个步骤&#xff1a; 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...

AspectJ 在 Android 中的完整使用指南

一、环境配置&#xff08;Gradle 7.0 适配&#xff09; 1. 项目级 build.gradle // 注意&#xff1a;沪江插件已停更&#xff0c;推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...

USB Over IP专用硬件的5个特点

USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中&#xff0c;从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备&#xff08;如专用硬件设备&#xff09;&#xff0c;从而消除了直接物理连接的需要。USB over IP的…...

Linux离线(zip方式)安装docker

目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1&#xff1a;修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本&#xff1a;CentOS 7 64位 内核版本&#xff1a;3.10.0 相关命令&#xff1a; uname -rcat /etc/os-rele…...