当前位置: 首页 > 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就这点东西。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Linux CentOS java JDK17
  • Python数据分析:Pandas与NumPy结合,实现高效数值计算,提升数据分析效率的最佳实践
  • Ubuntu10.04安装skyeye1.3.2问题
  • 如何使⽤组将⼀个文件拆分成多个文件 (LINQ)(C#)
  • Milvus向量数据库-内存中索引简介
  • 动手学深度学习7.5 批量规范化-笔记练习(PyTorch)
  • 将所有PPT中的字体颜色白色改成黑色---使用AI提高效率
  • Java-RestTemplate工具类
  • P1379 八数码难题 绿
  • PlayCanvas的EventHandler.on函数修改了返回值导致链式调用无法进行
  • 工 厂设计模式
  • 深度学习 vector 之模拟实现 vector (C++)
  • 无人机电子调速器详解!!!
  • 杀完进程,自动重启怎么办
  • Excel中的“块”操作
  • [js高手之路]搞清楚面向对象,必须要理解对象在创建过程中的内存表示
  • 0x05 Python数据分析,Anaconda八斩刀
  • CSS实用技巧
  • javascript 哈希表
  • LeetCode刷题——29. Divide Two Integers(Part 1靠自己)
  • nfs客户端进程变D,延伸linux的lock
  • react-core-image-upload 一款轻量级图片上传裁剪插件
  • react-native 安卓真机环境搭建
  • TypeScript实现数据结构(一)栈,队列,链表
  • Vue全家桶实现一个Web App
  • 大型网站性能监测、分析与优化常见问题QA
  • 对话 CTO〡听神策数据 CTO 曹犟描绘数据分析行业的无限可能
  • 翻译:Hystrix - How To Use
  • 回流、重绘及其优化
  • 力扣(LeetCode)965
  • 前端每日实战 2018 年 7 月份项目汇总(共 29 个项目)
  • 事件委托的小应用
  • 一文看透浏览器架构
  • 运行时添加log4j2的appender
  • SAP CRM里Lead通过工作流自动创建Opportunity的原理讲解 ...
  • 我们雇佣了一只大猴子...
  • ​油烟净化器电源安全,保障健康餐饮生活
  • # 手柄编程_北通阿修罗3动手评:一款兼具功能、操控性的电竞手柄
  • %check_box% in rails :coditions={:has_many , :through}
  • (2022版)一套教程搞定k8s安装到实战 | RBAC
  • (6)设计一个TimeMap
  • (8)Linux使用C语言读取proc/stat等cpu使用数据
  • (aiohttp-asyncio-FFmpeg-Docker-SRS)实现异步摄像头转码服务器
  • (day 12)JavaScript学习笔记(数组3)
  • (Matalb时序预测)PSO-BP粒子群算法优化BP神经网络的多维时序回归预测
  • (NO.00004)iOS实现打砖块游戏(九):游戏中小球与反弹棒的碰撞
  • (二十九)STL map容器(映射)与STL pair容器(值对)
  • (附源码)计算机毕业设计SSM疫情社区管理系统
  • (转)德国人的记事本
  • (转载)微软数据挖掘算法:Microsoft 时序算法(5)
  • **PHP分步表单提交思路(分页表单提交)
  • .NET 4 并行(多核)“.NET研究”编程系列之二 从Task开始
  • .NET BackgroundWorker
  • .NET/C# 反射的的性能数据,以及高性能开发建议(反射获取 Attribute 和反射调用方法)
  • .net中应用SQL缓存(实例使用)