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

奇异递归模板模式(Curiously Recurring Template Pattern)

奇异递归模板模式(Curiously Recurring Template Pattern) - 知乎 (zhihu.com)

本文来自上面的文章!!!本菜鸡学习和记录一下。

CRTP是C++模板编程时的一种惯用法:把派生类作为基类的模板参数。

1.静态多态

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

基类为Base,是模板类,子类Drived继承自Base同时模板参数为Drived,基类中有接口

interface而子类中有接口对应实现implementation,基类interface中将this通过static_cast转换为模板参数类型,这里是Drived,并调用该类型的implemention方法。

为什么是static_cast,而不是dynamic_cast?

因为只有继承了Base的类型才能调用interface且这里是向下转型,所以采用static_cast是安全的。

(不太理解)

通过CRTP可以使得类具有类似于虚函数的效果,同时没有虚函数调用时的开销(虚函数调用时需要通过虚函数指针查找虚函数表进行调用),同时类的对象的体积相比使用虚函数也会减少(不需要存储虚函数指针),但是缺点是无法动态绑定。

2.

template<typename Child>
class Animal
{
public:void Run(){static_cast<Child*>(this)->Run();}
};class Dog :public Animal<Dog>
{
public:void Run(){cout << "Dog Run" << endl;}
};class Cat :public Animal<Cat>
{
public:void Run(){cout << "Cat Run" << endl;}
};template<typename T>
void Action(Animal<T> &animal)
{animal.Run();
}int main()
{Dog dog;Action(dog);Cat cat;Action(cat);return 0;
}

Dog继承自Animal且模板参数为Dog,Cat继承自Animal且模板参数为Cat

Animal,Dog,Cat中都声明了Run,Animal中的Run是通过类型转换后调用模板类型的Run方法实现的。在Action模板参数中接收Animal类型的引用(或指针)并在其中调用了animal对象的Run方法,由于这里传入的是不同的子类对象,因此Action中的animal也会有不同的行为。

3.添加方法,减少冗余

//Vec3
struct Vector3
{float x;float y;float z;Vector3() = default;Vector3(float _x, float _y, float _z);inline Vector3& operator+=(const Vector3& rhs);inline Vector3& operator-=(const Vector3& rhs);//....
};inline Vector3 operator+(const Vector3& lhs, const Vector3& rhs);
inline Vector3 operator-(const Vector3& lhs, const Vector3& rhs);
//....//Vec2
struct Vector2
{float x;float y;Vector2() = default;Vector2(float _x, float _y);inline Vector2& operator+=(const Vector2& rhs);inline Vector2& operator-=(const Vector2& rhs);//....
};inline Vector2 operator+(const Vector2& lhs, const Vector2& rhs);
inline Vector2 operator-(const Vector2& lhs, const Vector2& rhs);
//....

 类型Vector3需要实现+=,-=,+,-等运算符重载。

 类型Vector2需要实现+=,-=,+,-等运算符重载。

其中+=,-=这两个运算符可以采取+,-运算符实现,这时候可以把+=,-=给抽象出来,减少代码冗余。

template<typename T>
struct VectorBase
{T& underlying() { return static_cast<T&>(*this); }T const& underlying() const { return static_cast<T const&>(*this); }inline T& operator+=(const T& rhs) { this->underlying() = this->underlying() + rhs;return this->underlying();}inline T& operator-=(const T& rhs){this->underlying() = this->underlying() - rhs;return this->underlying();}//.....
};struct Vector3 : public VectorBase<Vector3>
{float x;float y;float z;Vector3() = default;Vector3(float _x, float _y, float _z){x = _x;y = _y;z = _z;}
};inline Vector3 operator+(const Vector3& lhs, const Vector3& rhs)
{Vector3 result;result.x = lhs.x + rhs.x;result.y = lhs.y + rhs.y;result.z = lhs.z + rhs.z;return result;
}inline Vector3 operator-(const Vector3& lhs, const Vector3& rhs)
{Vector3 result;result.x = lhs.x - rhs.x;result.y = lhs.y - rhs.y;result.z = lhs.z - rhs.z;return result;
}
//......int main()
{Vector3 v0(6.0f, 5.0f, 4.0f);Vector3 v2(4.0f, 5.0f, 6.0f);v0 += v2;v0 -= v2;return 0;
}

在VectorBase中实现了+=,-=

它们依赖子类的+和-运算符的实现。

相关文章:

奇异递归模板模式(Curiously Recurring Template Pattern)

奇异递归模板模式(Curiously Recurring Template Pattern) - 知乎 (zhihu.com) 本文来自上面的文章&#xff01;&#xff01;&#xff01;本菜鸡学习和记录一下。 CRTP是C模板编程时的一种惯用法&#xff1a;把派生类作为基类的模板参数。 1.静态多态 #include <iostrea…...

【ArcGIS Pro实操第一期】最小成本路径(Least-cost path)原理及实操案例

ArcGIS Pro实操第一期&#xff1a;最小成本路径原理及实操案例 概述&#xff08;Creating the least-cost path&#xff09;1.1 原理介绍1.2 实现步骤1.3 应用案例 2 GIS实操2.1 工具箱简介2.1.1 成本路径&#xff08;Cost path&#xff09;2.1.2 成本距离&#xff08;Cost dis…...

探索C++编程技巧:计算两个字符串的最长公共子串

探索C编程技巧&#xff1a;计算两个字符串的最长公共子串 在C面试中&#xff0c;考官通常会关注候选人的编程能力、问题解决能力以及对C语言特性的理解。一个常见且经典的问题是计算两个字符串的最长公共子串&#xff08;Longest Common Substring, LCS&#xff09;。本文将详…...

等保2.0--安全计算环境--TiDB数据库

在使用本博客提供的学习笔记及相关内容时,请注意以下免责声明:信息准确性:本博客的内容是基于作者的个人理解和经验,尽力确保信息的准确性和时效性,但不保证所有信息都完全正确或最新。非专业建议:博客中的内容仅供参考,不能替代专业人士的意见和建议。在做出任何重要决…...

【unity实战】使用新版输入系统Input System+Rigidbody实现第三人称人物控制器(附项目源码)

最终效果 前言 使用CharacterController实现3d角色控制器&#xff0c;之前已经做过很多了&#xff1a; 【unity小技巧】unity最完美的CharacterController 3d角色控制器&#xff0c;实现移动、跳跃、下蹲、奔跑、上下坡、物理碰撞效果&#xff0c;复制粘贴即用 【unity实战】C…...

代码随想录算法训练营Day03 | 链表理论基础、203.移除链表元素 、707.设计链表、206.反转链表

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 链表理论基础203.移除链表元素思路与重点 707.设计链表思路与重点 206.反转链表思路与重点 链表理论基础 C/C的定义链表节点方式&#xff1a; // 单链表 struct L…...

【总结】CSS(SCSS) 不常用属性

1、设置 antd Meta 组件中 title 过长自动换行&#xff1a; .ant-card-meta-title {white-space: normal; /* 允许文本换行 */overflow: visible; /* 防止内容被截断 */text-overflow: clip; /* 禁用文本省略号 */} 2、选择器书写&#xff1a; .QR {&:hover {}} 3、设置文…...

电位计的模拟

该电位计的内部电阻在 270 范围内以“几乎”线性的方式从大约 15 欧姆变化到 220 欧姆。该设备的电流和电阻特性如下表所示&#xff1a; 计算曲线拟合以插入电位计欧姆电阻的非线性趋势非常简单。电位曲线如下&#xff1a; R16.2145((1.55848sqrt(x))*sin((-0.038222)*(-45.77…...

OSI七层网络协议

1、OSI各层数据的名称 7-5&#xff0c;应用层、表示层、会话层都叫做协议数据单元(PDU, Protocol Data Unit)。 4&#xff0c;传输层叫数据段(Segment)。 3&#xff0c;网络层叫数据包/报文(Packet)。 2&#xff0c;数据链路层叫数据帧(Frame)。 1&#xff0c;物理层叫比特流(…...

U盘提示需要格式化才能使用怎么办?教你轻松应对

U盘作为一种便捷的数据存储设备&#xff0c;广泛应用于日常工作和生活中。然而&#xff0c;有时我们会遇到U盘插入电脑后提示需要格式化才能使用的情况&#xff0c;这让人倍感焦虑&#xff0c;因为格式化往往意味着数据丢失。不过&#xff0c;在采取极端措施之前&#xff0c;我…...

Atom编辑器:曾经的效率提升利器,终将被新技术取代

Atom编辑器&#xff1a;曾经的效率提升利器&#xff0c;终将被新技术取代 哪个编程工具让你的工作效率翻倍 &#xff1f; 那么对我来说答案是 Atom。 作为一名Python开发者&#xff0c;我一直依赖Atom编辑器进行日常编程工作。在漫长的开发旅程中&#xff0c;Atom成为了我代码…...

立创商城9.9免邮活动开始啦!

从9月2日起&#xff0c;立创商城推出免邮活动&#xff0c;每月在领券中心>精选专区领取免邮券&#xff0c;即可享受满9.9元使用免邮券服务。 未注册的用户&#xff0c;可扫描下方二维码注册哦~...

图形几何-如何将凹多边形分解成若干个凸多边形

凹多边形的概念 凹多边形是指至少有一个内角大于180度的多边形。与之相对&#xff0c;凸多边形的所有内角均小于或等于180度&#xff0c;且任意两点之间的连线都完全位于多边形内部。将凹多边形分解成若干个凸多边形是计算几何中的一个重要问题。 分解原理 将凹多边形分解为凸…...

一个php快速项目搭建框架源码,带一键CURD等功能

介绍&#xff1a; 框架易于功能扩展&#xff0c;代码维护&#xff0c;方便二次开发&#xff0c;帮助开发者简单高效降低二次开发成本&#xff0c;满足专注业务深度开发的需求。 百度网盘下载 图片&#xff1a;...

STM32基础篇:RTC × Unix时间戳 × BKP

Unix时间戳 最早是在Unix系统使用的&#xff0c;之后很多由Unix演变而来的系统也都继承了Unix时间戳的规定。目前&#xff0c;Linux、Windows、安卓这些系统&#xff0c;其底层的计时系统都是使用Unix时间戳。 Uinx时间戳&#xff08;Unix Timestamp&#xff09;定义为从UTC/…...

Recyclerview部分列固定部分列滑动学习备忘

安卓使用RecyclerViewHorizontalScrollView 实现Item整体横向滑动 - 简书 (jianshu.com)https://www.jianshu.com/p/75bba86dd61c Android仿同花顺自选股列表控件介绍 RecyclerView的开发中&#xff0c;我们通常会遇到一行显示不下内容的情况&#xff0c;产品会 - 掘金 (jueji…...

【Python】路径(绝对路径、相对路径,当前工作目录),模块搜索路径(添加),Python安装路径,补充:cmd(命令行窗口)运行Python文件

Python中经常用到路径&#xff0c;比如&#xff1a;文件路径&#xff08;读取文件&#xff0c;保存文件等&#xff09;&#xff0c;模块搜索路径&#xff08;导入其他模块&#xff09;&#xff0c;Python安装路径。 而路径有两种&#xff1a;绝对路径&#xff0c;相对路径。在…...

Oceanbase 透明加密TDE

官方文档&#xff1a;数据库透明加密概述-V4.3.2-OceanBase 数据库文档-分布式数据库使用文档 OceanBase 数据库社区版暂不支持数据透明加密。 数据存储加密是指对数据和 Clog 等保存在磁盘中的数据进行无感知的加密&#xff0c;即透明加密&#xff08;简称 TDE&#xff09;。…...

图像去噪实验:基于全变分(TV)模型的MATLAB实现

一、背景 全变分模型在图像处理领域中被广泛用于去除噪声&#xff0c;同时保持图像边缘的清晰度。 二、实验步骤 图像的读取、噪声添加、去噪处理以及结果的显示。 三、实验仿真结果图 四、结论 全变分模型是一种有效的图像去噪方法&#xff0c;它能够在去除噪声的同时&#…...

97.WEB渗透测试-信息收集-Google语法(11)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a; 易锦网校会员专享课 上一个内容&#xff1a;96.WEB渗透测试-信息收集-Google语法&#xff08;10&#xff09; 2 、找上传类漏洞地址&…...

Cursor实现用excel数据填充word模版的方法

cursor主页&#xff1a;https://www.cursor.com/ 任务目标&#xff1a;把excel格式的数据里的单元格&#xff0c;按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例&#xff0c;…...

智慧医疗能源事业线深度画像分析(上)

引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会&#xff0c;其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具&#xff0c;对过去十年 WWDC 主题演讲内容进行了系统化分析&#xff0c;形成了这份…...

前端倒计时误差!

提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

大语言模型如何处理长文本?常用文本分割技术详解

为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

postgresql|数据库|只读用户的创建和删除(备忘)

CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文全面剖析RNN核心原理&#xff0c;深入讲解梯度消失/爆炸问题&#xff0c;并通过LSTM/GRU结构实现解决方案&#xff0c;提供时间序列预测和文本生成…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2

每日一言 今天的每一份坚持&#xff0c;都是在为未来积攒底气。 案例&#xff1a;OLED显示一个A 这边观察到一个点&#xff0c;怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 &#xff1a; 如果代码里信号切换太快&#xff08;比如 SDA 刚变&#xff0c;SCL 立刻变&#…...

人机融合智能 | “人智交互”跨学科新领域

本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...

DBLP数据库是什么?

DBLP&#xff08;Digital Bibliography & Library Project&#xff09;Computer Science Bibliography是全球著名的计算机科学出版物的开放书目数据库。DBLP所收录的期刊和会议论文质量较高&#xff0c;数据库文献更新速度很快&#xff0c;很好地反映了国际计算机科学学术研…...