Curiously Recurring Template Pattern奇怪的模板递归 --- C++20

Curiously Recurring Template Pattern 奇怪的模板递归 — C++20

我们都知道C++有静态多态和动态多态,动态多态通过虚函数表实现,他的缺点就是对效率产生一点点影响

可以用CRTP解决这个问题

我们先举一个动态多态的例子:

#include <iostream>
using namespace std;class Base
{
public:virtual void invoking(){cout << "Base" << endl;}
};class Derived1 final : public Base
{
public:virtual void invoking() override final{cout << "Derived1" << endl;}
};class Derived2 final : public Base
{
public:virtual void invoking() override final{cout << "Derived2" << endl;}
};int main()
{Derived1* derived1 = new Derived1;Derived2* derived2 = new Derived2;derived1->invoking();derived2->invoking();}

会在运行时查找虚函数表,影响运行时效率

使用CRTP编译器多态

特点:子类继承基类,且基类有一个模板参数,并以子类类型为参数

#include <iostream>
using namespace std;template <typename Derived>
class Base
{
public:void interface(){static_cast<Derived*>(this)->implementation();}void implementation(){cout << "Implementation Base" << endl;}
};class Derived1 :public  Base<Derived1>
{
public:void implementation(){cout << "Implementation Derived1" << endl;}
};class Derived2 : public  Base<Derived2>
{
public:void implementation(){cout << "Implementation Derived2" << endl;}
};class Derived3 : public Base<Derived3>
{
public:
};template <typename T>
void execute(T& base)
{base.interface();
}int main(int argc, char* argv[])
{Derived1 d1;execute(d1);Derived2 d2;execute(d2);Derived3 d3;execute(d3);
}

每个基类都调用 base.interface(); 然后调用static_cast<Derived*>(this)->implementation();

这样就在编译器实现了多态,避免了动态多态

1>class Base<class Derived1>	size(1):
1>	+---
1>	+---
1>class Base<class Derived2>	size(1):
1>	+---
1>	+---
1>class Base<class Derived3>	size(1):
1>	+---
1>	+---

image-20220609223403879

#include <chrono>
#include <iostream>auto start = std::chrono::steady_clock::now();void writeElapsedTime() {auto now = std::chrono::steady_clock::now();std::chrono::duration<double> diff = now - start;std::cerr << diff.count() << " sec. elapsed: ";
}template <typename ConcreteMessage>                        // (1)
struct MessageSeverity {void writeMessage() {                                     // (2)static_cast<ConcreteMessage*>(this)->writeMessageImplementation();}void writeMessageImplementation() const {std::cerr << "unexpected" << std::endl;}
};struct MessageInformation : MessageSeverity<MessageInformation> {void writeMessageImplementation() const {               // (3)std::cerr << "information" << std::endl;}
};struct MessageWarning : MessageSeverity<MessageWarning> {void writeMessageImplementation() const {               // (4)std::cerr << "warning" << std::endl;}
};struct MessageFatal : MessageSeverity<MessageFatal> {};     // (5)template <typename T>
void writeMessage(T& messServer) {writeElapsedTime();messServer.writeMessage();                            // (6)}int main() {std::cout << std::endl;MessageInformation messInfo;writeMessage(messInfo);MessageWarning messWarn;writeMessage(messWarn);MessageFatal messFatal;writeMessage(messFatal);std::cout << std::endl;}

Info;
writeMessage(messInfo);

MessageWarning messWarn;
writeMessage(messWarn);MessageFatal messFatal;
writeMessage(messFatal);std::cout << std::endl;

}


![image-20220609224336869](https://img-blog.csdnimg.cn/img_convert/4ed12bcf5b8ae5ceeaa9a1575e87989a.png)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/407953.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

关于table的中元素对齐方式的注意点

情形一&#xff1a;<td></td>中嵌套了div或table元素。 1。td中的内部元素(如div)设置了height属性&#xff0c;td中设置了vertical-align的情况下&#xff0c;在IE中&#xff0c;td的vertical-align不起作用&#xff0c;但在firefox中是起作用的。 2。如果td中未…

不要带我去看鱼了

我在企业里面上班。每天中午都得回家吃午饭。儿子才3岁。每每见我总是要我抱&#xff0c;我经常出差什么的&#xff0c;儿子都怕我走了。每次我要离开的时候&#xff0c;只好让老婆抱着儿子遮住&#xff0c;让我悄悄地离开。儿子便猛哭。老婆只好带着儿子到家门口的池塘旁边去看…

char 与 String 相等比较

这是一个相当2 相当基础 相当没有意义的帖子&#xff1b;但今天因为这个问题引发了一个bug。小细节也很重要&#xff01;&#xff01;&#xff01; char a1;// char b2dsf; //char 表示单个字符 char c1; //不需要单引号也能表示// System.out.println(a.equals(&q…

我眼中的金蝶ERP

在我的博克回复里&#xff0c;有个小雨的博友问我是否了解金蝶ERP&#xff0c;我答应给她说说金蝶ERP&#xff0c;所以就有了这份文章。在我们国内&#xff0c;最出名的或者说市场占有率前两位的就是用友和金蝶了。至于到底谁排名先排名后一点&#xff0c;这不是我想说的范围。…

什么是JDO

From: http://blog.csdn.net/wp_84/archive/2007/09/02/1769481.aspx Java数据对象(Java Data Objects,JDO)是一个应用程序接口(API),它是Java程序员能够间接地访问数据库,也就是说,不需使用直接的结构化查询语言(SQL)语句.JDO是作为Java数据库连接(JDBC)的一个补充来介绍的,而…

PROJECT #0 - C++ PRIMER [CMU 15-445645]笔记

PROJECT #0 - C PRIMER [CMU 15-445/645]笔记 这是数据库领域的一门课程, 由卡内基梅隆大学副教授Andy Pavlo授课, 目前在网上有授课视频资料、实验以及配套的在线测评环境 (限时开放至2021年12月31日) 环境: wsl2 Clion Project #0 - C Primer 还是很简单的,主要目的是让…

简单JS实现对表的行的增删

这段代码非常的简单&#xff0c;仅仅作为自己的一个小小的记录&#xff01; ok&#xff0c;先上一个简单的图例&#xff0c;效果如下&#xff08;注意&#xff1a;这只是一个简单的例子&#xff0c;不过可以根据这个简单的例子&#xff0c;变化出更为复杂的效果&#xff09;&am…

用 JavaScript 操作字符串

虽然 JavaScript 有很多用处&#xff0c;但是处理字符串是其中最流行的一个。下面让我们深入地分析一下使用 JavaScript 操作字符串。在 JavaScript 中&#xff0c; String 是对象。 String 对象并不是以字符数组的方式存储的&#xff0c;所以我们必须使用内建函数来操纵它们的…

The Ranges Library --- C++20

The Ranges Library — C20 ranges可以让我们更加舒服的写代码了, 不用再敲那么多的代码 之前我们需要这样标准库的算法对容器的操作 #include <iostream> #include <ranges> #include <vector> #include <algorithm>int main() {std::vector vec{ …

什么是反射(.NET)[转]

From: http://www.cnblogs.com/zxsoft/archive/2007/09/17/895236.html 反射&#xff08;Reflection&#xff09;是.NET中的重要机制&#xff0c;通过放射&#xff0c;可以在运行时获得.NET中每一个类型&#xff08;包括类、结构、委托、接口和枚举等&#xff09;的成员&#x…

Yii权限管理工具Srbac使用小结

一、关于Srbac Srbac是基于Yii 框架的 RBAC&#xff08;基于角色的访问控制&#xff09; 插件模块&#xff0c;用于帮助Yii开发人员更方便地进行权限控制&#xff0c;在实际应用过程中也比较方便。 二、安装配置Srbac 在Yii的官方网站的Extensions中已经收录了Srbac插件&#x…

概念concept和requires ---C++ 20

概念concept和requires —C 20 concept concept简化了模板编程的难度 我们可以使用**concept定义模板形参的约束条件T** 模板实力替换T后必须满足std::is_integral_v<C>;为true 例子: requires关键字可以直接约束模板形参T 如下: template <class C> concept …

辞职中

不知道为什么就不想再做下去了&#xff0c;说不上来工作有什么好&#xff0c;当然也说不上来什么不好。SP这个行业&#xff0c;可能不太适合我。准备走了&#xff0c;考研还是继续找工作&#xff1f;我不知道该怎么走&#xff01;看着前面都是路却找不到一条适合自己的。转载于…

向DataGridView中添加新的一行数据,可以添加到最后一行或作为第一行

我的开发环境&#xff1a;Microsoft Visual Studio .net 2005 这个程序是Windows Forms Application 新建一个Windows Forms Application项目&#xff0c;打开Form1&#xff0c;在窗体上放一个DataGridView控件和Button,在DataGridView的Columns中添加两列&#xff0c;Name分别…

Linq学习

IEnumerable<DataRow> cbCurrent from dr in cbRows.AsEnumerable() where dr.Field<string>("ObjectNO").ToString() row["运输单号"].…