C++设计新思维(泛型编程与设计模式之应用)之常整数映射为类别(2.4)

news2024/9/23 3:22:02

技术

模板偏特化,模板全特化

应用

1、有必要根据一个编译期常数调用一个或数个不同的函数
2、有必要在编译器实施"分派"(dispatch)

例子

如果打算在执行期进行分派(dispatch),可使用if-else或switch语句。大部分时候其执行期成本都微不足道。然后你还是无法常常那么做,因为if-else语句要求每一个分支都得编译成功。

假设你想设计一个泛型容器NiftyContainer,它将元素类型参数化:

template <class T>
class NiftyContainer
{
	...
	// 假设NiftyContainer内含指针,指向类型为T的对象。
};

为了复制NiftyContainer里的某个对象,你想调用其拷贝构造函数(针对非多态类)或虚函数clone()(针对多态类型)。
你以一个bool来作为调用哪种函数的条件

template <class Tbool isPolymorphic>
class NiftyContainer
{
	...
	void doSomething()
	{
		T *pSomeObj = ...;
		if (isPolymorphic) { // 多态
			T *pNewObj = pSomeObj->clone(); 
		} else { // 非多态
			T *pNewObj = new T(*pSomeObj);
			// T *pNewObj = new T();
			// *pNewObj = *pSomeObj;
		}
	}
};

问题是,编译器并不一定都会编译成功,如果使用多态算法,那么对于任何一个未定义clone函数的类或者clone是private的类,都将使doSomething函数无法编译成功。而对于非多态类型,如果禁用了拷贝构造或者拷贝构造在private区域也同样将无法编译成功。所以想要编译成功,则T类型必须同时具有clone()拷贝构造函数才能编译成功。
如果我只需要clone拷贝构造函数中的一种呢?
虽然有很多种解法,但是以下这种解法最简单易理解。

template <int v>
struct Int2Type
{
	enum { value = v };
};

template <class T, bool isPolymorphic>
class NiftyContainer
{
public:
	void doSomething(T *pObj)
	{
		doSomething(pObj, Int2Type<isPolymorphic>());
	}

private:
	void doSomething(T *pObj, Int2Type<true>)
	{
		T *pNewObj = pObj->clone();
	}
	
	void doSomething(T *pObj, Int2Type<false>)
	{
		T *pNewObj = new T(*pObj);
	}
};

这种手法在STL代码中很常见,只是形式略有不同而已。
这种小技巧之所以有效,最主要原因是编译器不会编译一个未被使用到的template函数,只会对它做语法检测。至于此技巧之所以有用,是因为在template代码中大部分情形要在编译期做流程分派动作。

测试

/*************************************************************************
    > File Name: main.cc
    > Author:
    > Brief:
    > Created Time: Mon 23 Jan 2023 03:46:27 PM CST
 ************************************************************************/

#include <iostream>
using namespace std;

template <int v>
struct Int2Type
{
    enum
    {
        value = v
    };
};

template <class T, bool isPolymorphic>
class NiftyContainer
{
public:
    void doSomething(T *pObj)
    {
        doSomething(pObj, Int2Type<isPolymorphic>());
    }

private:
    void doSomething(T *pObj, Int2Type<true>)
    {
        T *pNewObj = pObj->clone();
    }

    void doSomething(T *pObj, Int2Type<false>)
    {
        T *pNewObj = new T(*pObj);
        delete pNewObj;
    }
};

class Test
{
public:
    Test() { printf("%s()\n", __func__); }
    Test(const Test &o) { printf("%s(const Test &o)\n", __func__); }
    ~Test() { printf("%s()\n", __func__); }
};

int main(int argc, char **argv)
{
    Test t;
    NiftyContainer<Test, false> container;
    container.doSomething(&t);
    return 0;
}

在这里插入图片描述

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

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

相关文章

windows权限维持方法详解

权限维持在获取服务器权限后&#xff0c;为了防止服务器管理员发现和修补漏洞而导致对服务器权限的丢失&#xff0c;测试人员往往需要采取一些手段来实现对目标服务器的持久化访问。权限持久化&#xff08;权限维持&#xff09;技术就是包括任何可以被测试人员用来在系统重启、…

Allegro如何通过飞线判断同一个网络连接位是否在同一直线操作指导

Allegro如何通过飞线判断同一个网络连接位是否在同一直线操作指导 Allegro可以通过飞线判断同一个网络的连接位是否在同一条直线上,如下图 当飞线是类似三角形的时候,可以判定两个连接点位是在同一条直线上 具体设置操作如下 选择Setup选择Design Parameter

React源码之render过程中发生了什么?

理解JSX 对于我们直接书写jsx语法&#xff0c;我们的浏览器是不理解我们这种语法的&#xff0c;所以需要babel来去转义&#xff0c;那么可以通过plugin-transform-react-jsx来转译jsx语法&#xff0c;使得浏览器可以识别我们的Jsx语法&#xff0c;例如&#xff1a; <div&g…

关于xshell简答使用

xshell是一个远程工具下载 官网地址&#xff1a;https://www.xshell.com/zh/xshell/直接下载即可~选择免费的授权页面 下载 不然要收费 也不要用盗版。运行后的xshell界面我们要建立服务器的连接点击加号 新建连接 即可 输入连接地址后 要输入 账号 和 秘密 OK 好了 可以使用了…

【Linux】Linux编译器gcc、g++

文章目录&#x1f3aa; Linux编译器gcc、g&#x1f680;1. 程序的编译⭐1.1 预处理⭐1.2 编译⭐1.3 汇编⭐1.4 链接⭐1.5 gcc/g常用指令&#x1f680;2. 函数库⭐2.1 静态库⭐2.2 动态库⭐2.3 动静态库对比&#x1f3aa; Linux编译器gcc、g 我们这以gcc为例&#xff0c;g编译器…

【学习笔记之数据结构】树的认识

树的概念&#xff1a; 树是一种非线性的数据结构&#xff0c;它由n&#xff08;n可以为0&#xff09;个有限的节点组成一个具有层次关系的结合。之所以把它称之为树是因为它的逻辑结构形似一个倒着的树。它的根在上面&#xff0c;叶子在下面。   有一个特殊的节点&#xff0c…

WebRTC系列-Qos系列之接收NACK

文章目录 1. 主要调用流程1.1 RTCP和RTP包区分1.2 查找丢失包2. RTX在文章 WebRTC系列-Qos系列之RTP/RTCP源码分析-RTP/RTCP包解析-3的2.3.3章节介绍了NACK包在WebRTC中解析方式及RFC规定协议的定义。 这篇文章开始,详细分析其接受RTCP包到解析nack的处理流程; 1. 主要调用流…

Kotlin中空安全操作符,异常处理和自定义异常,以及先决条件函数详解

博主前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住也分享一下给大家 &#x1f449;点击跳转到教程 一、Kotlin的可空性 null 在java中我们司空见惯的空指针异常NullPointerException,带给了我们很多麻烦。 Kotlin作为更强…

STM32编写OLED显示屏驱动

文章目录前言一、OLED的器件地址二、编写写数据和写命令函数三、编写初始化OLED屏幕函数四、其他功能函数编写五、显示字符和数字函数编写总结前言 这篇文章将带大家学习如何编写OLED显示屏的驱动程序。这里我使用的是HAL库的硬件IIC&#xff0c;OLED屏幕使用的是SSD1306的。 …

sbt编程语言scala的构建工具配置及项目构建(附带网盘下载)

SBT简介 SBT 是 Scala 的构建工具&#xff0c;全称是 Simple Build Tool&#xff0c; 类似 Maven 或 Gradle。 Java可以用Maven快速构建项目&#xff0c;scala用SBT快速构建一个Scala项目。 sbt下载官网 百度网盘链接&#xff1a;https://pan.baidu.com/s/1eJkdWndZ0izcd3w…

Elasticsearch7.8.0版本高级查询——桶聚合查询文档

目录一、初始化文档数据二、桶聚合查询文档2.1、概述2.2、terms 聚合&#xff0c;分组统计的示例2.3、在 terms 分组下再进行聚合的示例一、初始化文档数据 在 Postman 中&#xff0c;向 ES 服务器发 POST 请求 &#xff1a;http://localhost:9200/user/_doc/1&#xff0c;请求…

Yolo系列理论

参考文章&#xff1a;AI菌的YOLO系列 目标检测-Yolo系列发展Anchors Base原理Anchors Free原理YOLO v1Yolov1网络结构Yolov1实现方法Yolov1损失函数Yolov1总结YOLO v2Yolov2网络结构Yolov2改进细节Yolov2总结YOLO V3Yolov3网络结构YOLO V4Yolov4网络结构YOLOv4 BackBone训练策略…

数据库搏击

1. Mysql入门 1.1 Mysql5.7 安装配置 1.2 命令行连接到Mysql 1.3 图形化软件 1.3.1 Navicat SQLyog 1.4 数据库三层结构 所有安装Mysql数据库&#xff0c;就是在主机安装一个数据库管理系统(DBMS)&#xff0c;这个管理程序可以管理多个数据库。DBMS(database mana…

设计模式 - 六大设计原则之LSP(里氏替换)

文章目录概述里氏替换原则问题由来里氏替换的原则里氏替换原则的作用CaseBad ImplBetter Impl抽象银行卡类储蓄卡实现类信用卡实现类单元测试小结概述 里氏替换原则&#xff08;Liskov Substitution Principle , LSP&#xff09; 由麻省理工学院计算机科学西教授 Barbara Lisk…

MySQL两种引擎的索引

推荐看看这个视频&#xff0c;将两种引擎实现的索引原理说的比较清楚 4-2 索引概述 本文转载&#xff1a;想飞的盗版鱼的博客​​​​​​ mysql5.5之后都是用idb了 补充一个主键和索引的关系&#xff1a;Are You OK&#xff1f;主键就是聚集索引吗&#xff1f; 索引类型…

五个简单常用的系统命令

一、文件扫描修复 以管理员身份进入命令提示符&#xff0c;输入Sfc空格/scannow 二、使用Check disk命令检查并修复磁盘错误 1、开机时连续不断的点击F11键&#xff0c;选择&#xff08;疑难解答&#xff09;-选择&#xff08;高级选项&#xff09;-选择&#xff08;命令提示…

virtualbox运行Ubuntu系统

virtualbox安装 下载virtualbox VirtualBox 7.0.6版本下载 安装virtualbox 点击执行VirtualBox-7.0.6-155176-Win.exe即可&#xff0c; 直接点击"下一步" 直到 “完成” 导入以有的ova虚拟机文件 1&#xff09;点击导入 2&#xff09;选择下载的ova文件 3&a…

GD32F4——定时器(TIMERx)

一、概述 定时器的主要功能是用来计时&#xff0c;时间到达之后可以产生中断&#xff0c;提醒计时时间到&#xff0c;然后可以在中断函数中去执行功能。 GD32F450ZGT6共14个定时器&#xff0c;分别为 &#xff08;1&#xff09;高级定时器&#xff08;TIMERx&#xff0c;x0,…

LightGBM介绍

LightGBM介绍 GBDT是机器学习中一个长盛不衰的模型&#xff0c;其主要思想是利用弱分类器&#xff08;决策树&#xff09;迭代训练以得到最优模型&#xff0c;该模型具有训练效果好&#xff0c;不易过拟合等优点。GBDT不仅在工业界应用广泛&#xff0c;通常被应用于多分类、点…

【ONE·C || 数据存储】

总言 C语言&#xff1a;数据存储相关介绍。 文章目录总言1、基本数据类型介绍1.1、整体介绍1.2、各数据类型分别说明&#xff08;整型、浮点型、构造、指针、空&#xff09;2、整型在内存中的存储2.1、原码、反码、补码2.1.1、总体介绍2.1.2、char、short类型在内存中的存储范围…