c++工厂注册类

工厂注册类

利用模版形式注册类

#include <iostream>
#include <memory>
#include <functional>
namespace cyn {//自定义断言
//#ifndef _DEBUG // _RELEASE  或者 _DEBUG  ,根据你的编译器/构建系统
#ifdef _DEBUG // _RELEASE  或者 _DEBUG  ,根据你的编译器/构建系统
#define CHECK(cond) \do { \if (!(cond)) { \std::cerr << "Assertion failed: (" << #cond << "), function " << __FUNCTION__ \<< ", file " << __FILE__ << ", line " << __LINE__ << "." << std::endl; \
} \
} while (0)
#define CHECK_EX(cond, msg) \do { \if (!(cond)) { \std::cerr << "Assertion failed: (" << #cond << "), function " << __FUNCTION__ \<< ", file " << __FILE__ << ", line " << __LINE__ << "." << std::endl; \std::cerr << "Message: " << msg << std::endl; \throw std::runtime_error(msg); \
} \
} while (0)
#else
#define CHECK(cond) \do { \\
} while (0)
#define CHECK_EX(cond, msg) \do { \\
} while (0)
#endif// 参数基类
class LayerParams
{
public:virtual ~LayerParams() = default;
};
// 具体参数类型
class DenseLayerParams : public LayerParams {
public:int units;float learning_rate;DenseLayerParams(int units, float learning_rate) : units(units), learning_rate(learning_rate) {}
};// 基类
class Layer
{
public:Layer(const std::string& name,const std::shared_ptr<LayerParams>& params) : name(name),layer_params(params){}virtual int forward(int){return 0;};public:int input_;std::string name;std::shared_ptr<LayerParams> layer_params;
};//获取类型名字
template <typename T>
constexpr auto class_type_name() noexcept
{std::string_view name, prefix, suffix;
#ifdef _MSC_VERname = __FUNCSIG__;prefix = "auto __cdecl cyn::class_type_name<class cyn::";suffix = ">(void) noexcept";
#elif defined(__GNUC__)name = __PRETTY_FUNCTION__;prefix = "constexpr auto cyn::class_type_name() [with T = cyn::";suffix = "]";
#elif defined(__clang__)name = __PRETTY_FUNCTION__;prefix = "constexpr auto cyn::class_type_name() [with T = cyn::";suffix = "]";#endifname.remove_prefix(prefix.size());name.remove_suffix(suffix.size());return name;
}// 定义一个注册表基类模版
template <typename T, typename... Args>
class Factory
{using CreateFunction = std::function<std::shared_ptr<T>(Args...)>;Factory(){}public:virtual ~Factory() = default;static Factory& Instance(){static Factory instance;return instance;}void Register(const std::string & name,const CreateFunction& create){std::cout <<"Factory Register name:"<< std::string(name) << std::endl;registry[std::string(name)] = create;}std::shared_ptr<T> Create(const std::string& name,Args... args){if (registry.find(name) != registry.end()){std::cout <<"Create succeed:"<< std::string(name) << std::endl;return registry[name](args...);}std::cout <<"Create fail:"<< std::string(name) << std::endl;return nullptr;}
private:std::unordered_map<std::string, CreateFunction> registry;
};
//注册类 统一接口
template <typename Base, typename Impl, typename... Args>
class Register
{
public:explicit Register(){std::cout<<"Register name:  "<<std::string(class_type_name<Impl>())<<std::endl;//流程6Factory<Base, Args...>::Instance().Register(std::string(class_type_name<Impl>()), [](Args... args){return std::shared_ptr<Base>(new Impl(args...));});}
};// LayerSub  在这很关键,实现了继承LayerSub  (也就是继承基类)自动注册
//注册Layer子类,实现继承自动注册  T 为Layer子类类型
/** 继承LayerSub-构造函数->(void)registered->trigger()->_register(str)*/
template <typename T>
class LayerSub : public Layer
{//流程4static bool trigger(){//流程5Register<Layer,T,std::shared_ptr<LayerParams>> _register;return true;}
protected://流程2LayerSub(const std::shared_ptr<LayerParams>& params) : Layer(std::string(class_type_name<T>()),params){std::cout<<"LayerSub:"<<std::string(class_type_name<T>())<<std::endl;//流程3(void)registered;}public:static bool registered;};
template <typename T>
bool LayerSub<T>::registered = LayerSub<T>::trigger();//定义Layer类 创建接口
typedef Factory<Layer, std::shared_ptr<LayerParams>> LayerFactory;// 具体层类型class DenseLayer : public LayerSub<DenseLayer>
{
public:DenseLayer(const std::shared_ptr<LayerParams>& params) : LayerSub(params){std::cout<<"DenseLayer constructor!"<<std::endl;std::shared_ptr<DenseLayerParams> p = std::dynamic_pointer_cast<DenseLayerParams>(params);//检查参数类型 - 调试用CHECK_EX(p,"error");//打印参数值std::cout<<p->units<<std::endl;std::cout<<p->learning_rate<<std::endl;}int forward(int s) override  {std::cout<<"wo shi zi lei!"<<s<<std::endl;return s;}
};}int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);std::shared_ptr<cyn::DenseLayerParams> param = std::make_shared<cyn::DenseLayerParams>(100,1);auto ss = cyn::LayerFactory::Instance().Create(std::string("DenseLayer"), param);ss->forward(1);return a.exec();
}

输出结果:
Register name: DenseLayer
Factory Register name:DenseLayer
Create succeed:DenseLayer
LayerSub:DenseLayer
DenseLayer constructor!
100
1
wo shi zi lei!1

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

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

相关文章

百度地图高级进阶开发:圆形区域周边搜索地图监听事件(覆盖物重叠显示层级\图像标注监听事件、setZIndex和setTop方法)

百度地图API 使用百度地图API添加多覆盖物渲染时&#xff0c;会出现覆盖物被相互覆盖而导致都无法触发它们自己的监听&#xff1b;在百度地图API里&#xff0c;map的z-index为0&#xff0c;但是触发任意覆盖物的监听如click时也必定会触发map的监听&#xff1b; 项目需求 在…

最详细STM32,cubeMX 点亮 led

这篇文章将详细介绍 如何在 stm32103 板子上点亮一个LED. 文章目录 前言一、开发环境搭建。二、LED 原理图解读三、什么是 GPIO四、cubeMX 配置工程五、解读 cubeMX 生成的代码六、延时函数七、控制引脚状态函数点亮 LED 八、GPIO 的工作模式九、为什么使用推挽输出驱动 LED总结…

HashSet编程小案例,控制生日和姓名。重写HashCode

Java编程&#xff1a; 定义员工Employee类&#xff0c;该类包含&#xff1a;private成员属性name&#xff0c;sal&#xff0c;birthday(MyDate类型)&#xff0c; 其中birthday为MyDate类型(属性包括&#xff1a;year&#xff0c;month&#xff0c;day)&#xff0c; 要求&…

基于svg+js实现简单动态时钟

实现思路 创建SVG容器&#xff1a;首先&#xff0c;创建一个SVG容器元素&#xff0c;用于容纳时钟的各个部分。指定SVG的宽度、高度以及命名空间。 <svg width"200" height"200" xmlns"http://www.w3.org/2000/svg"><!-- 在此添加时钟…

排查手机应用app微信登录问题不跳转失败原因汇总及其解决方案

经过最近我发的文章,我个人觉得解决了不少小问题,因为最近很小白的问题已经没有人私聊问我了,我总结了一下排查手机应用app微信登录问题不跳转失败的原因汇总及其解决方案在这篇文章中,分析微信登录不跳转的原因,并提供解决方案。希望通过这篇文章,能够帮助大家顺利解决这…

LCR 001. 两数相除

剑指Offer通关 力扣搜索LCR即为剑指Offer的所有题目。 LCR 001. 两数相除 快速乘 解析&#xff1a; 题目规定只能用32位整数&#xff0c;所以取值范围在-2^31 ~ 2^31 - 1 之间。这里的特殊情况为什么不考虑被除数和除数为最大值&#xff1f;因为后面会将所有的数都转为负数…

【科研绘图】将echarts中的散点地图和热力地图融合到同一个地图上

将echarts中的散点地图和热力地图融合到同一个地图上 散点地图热力地图散点热力地图散点地图 官网示例代码 from pyecharts import options as opts from pyecharts.charts import Geo from pyecharts.faker import Faker from pyecharts.globals import ChartTypec = (Geo

紫光同创FPGA实现UDP协议栈网络视频传输,带录像和抓拍功能,基于YT8511和RTL8211,提供2套PDS工程源码和技术支持

目录 1、前言免责声明 2、相关方案推荐我这里已有的以太网方案紫光同创FPGA精简版UDP方案紫光同创FPGA带ping功能UDP方案紫光同创FPGA精简版UDP视频传输方案 3、设计思路框架OV5640摄像头配置及采集数据缓冲FIFOUDP协议栈详解MAC层发送MAC发送模式MAC层接收ARP发送ARP接收ARP缓…

DCDC Buck电路地弹造成的影响

很多读者都应该听过地弹&#xff0c;但是实际遇到的地弹的问题应该很少。本案例就是一个地弹现象导致电源芯片工作不正常的案例。 問題描述 如下图1 &#xff0c;产品其中一个供电是12V转3.3V的电路&#xff0c;产品发货50K左右以后&#xff0c;大约有1%的产品无法启动&#…

4.MidBook项目经验之MonogoDB和easyExcel导入导出

1.数据字典(固定的数据,省市级有层级关系的) //mp表如果没有这个字段,防报错,eleUI需要这个字段TableField(exist false) //父根据id得到子数据 ,从controller开始自动生成代码-->service//hasChildren怎么判断,只需要判断children的parentid的count数量>0就可以了//优化…

vue.js - 断开发送的请求,解决接口重复请求数据错误问题(vue中axios多次相同请求中断上一个)

描述 进入页面时第一个接口还在请求,立即切换tab请求第二个接口。但是第二个接口响应比第一个接口响应快,页面展示的时第一个接口的数据,如图: 解决方法 判断如果是相同的接

visual studio安装时候修改共享组件、工具和SDK路径方法

安装了VsStudio后,如果自己修改了Shared路径&#xff0c;当卸载旧版本&#xff0c;需要安装新版本时发现&#xff0c;之前的Shared路径无法进行修改&#xff0c;这就很坑爹了&#xff0c;因为我运行flutter程序的时候&#xff0c;报错找不到windows sdk的位置&#xff0c;所以我…

怎么把flac音频变为mp3?

怎么把flac音频变为mp3&#xff1f;FLAC音频格式在许多平台和应用程序中都得到支持和应用。FLAC音频格式被广泛支持和应用。许多平台、设备和应用程序都支持FLAC格式&#xff0c;如Windows、macOS和Linux操作系统、各种音乐播放器软件、智能手机和平板电脑、在线音乐平台和流媒…

c++小知识

内联函数 inline 用来替换宏函数 不能分文件编辑 在c语言中#define NULL 0在c中使用nullptr表示空指针class内存的大小计算规则使用的是内存对齐 没有成员&#xff0c;但是还有1个字节&#xff0c;我们使用这个来标记他是个类 类成员函数不存在于类中 为什么每个对象使用的…

基于Linux安装Hive

Hive安装包下载地址 Index of /dist/hive 上传解压 [rootmaster opt]# cd /usr/local/ [rootmaster local]# tar -zxvf /opt/apache-hive-3.1.2-bin.tar.gz重命名及更改权限 mv apache-hive-3.1.2-bin hivechown -R hadoop:hadoop hive配置环境变量 #编辑配置 vi /etc/pro…

云安全—云计算基础

0x00 前言 学习云安全&#xff0c;那么必然要对云计算相关的内容进行学习和了解&#xff0c;所以云安全会分为两个部分来进行&#xff0c;首先是云计算先关的内容。 0x01 云计算 广泛传播 云计算最早大范围传播是2006年&#xff0c;8月&#xff0c;在圣何塞【1】举办的SES&a…

SpringMVC的响应处理

目录 传统同步业务数据的响应 请求资源转发 请求资源重定向 响应数据模型 直接回写数据给客户端 前后端分离异步业务数据响应 在前面的文章中&#xff0c;我们已经介绍了Spring接收请求的部分&#xff0c;接下来看Spring如何给客户端响应数据 传统同步业务数据的响应 准…

网页数据采集HTTP Get,Post登录提交数据--VBS之Microsoft.XMLHTTP对象

MSXML中提供了Microsoft.XMLHTTP对象&#xff0c;能够完成从数据包到Request对象的转换以及发送任务。 创建XMLHTTP对象的语句如下&#xff1a; Set objXML CreateObject("Msxml2.XMLHTTP") 或 Set objXML CreateObject(“Microsoft.XMLHTTP”) Or, for version 3…

CSS3 按钮

创建 CSS3 按钮可以通过组合样式属性和伪类来实现 <!DOCTYPE html> <html> <head><link rel"stylesheet" type"text/css" href"styles.css"> </head> <body><button class"basic-button">…

Redis数据结构之quicklist

前言 为了节省内存&#xff0c;Redis 推出了 ziplist 数据类型&#xff0c;采用一种更加紧凑的方式来存储 hash、zset 元素。因为查找的时间复杂度是 O(N)&#xff0c;且写入需要重新分配内存&#xff0c;所以它仅适用于小数据量的存储&#xff0c;而且它还存在 连锁更新 的风…