Windows下编译RTTR

虽然C++11引入了RTTI、Metaprogramming 等技术,但C++在Reflection编程方面依旧功能有限。在社区上,RTTR则提供了一套C++编写的反射库,补充了C++在Reflection方面的缺陷。

零、环境

操作系统Windows 11
Visual StudioVisual Studio Community 2022 
CMakeCMake 3.24.2
DoxygenDoxygen-1.9.8

一、下载源码

从GitHub拉取RTTR代码:

git clone https://github.com/rttrorg/rttr.git

二、编译

按照下表配置CMake,并完成构建与生成,

Where is the source codeWindows 11
Where to build the binariesVisual Studio Community 2022 
CMAKE_INSTALL_PREFIXCMake 3.24.2

打开rttr.sln,构建"ALL_BUILD"完成RTTR编译;构建"INSTALL"完成RTTR安装。

三、源码分析

虽然各种反射机制的具体实现有所不同,但大体思路还是一致的:

  • 生成类型元数据

类型元数据包括构造函数、属性、方法等,类型元数据可以在编译阶段自动生成,也可以在运行阶段手动注册;

  • 执行反射

需要执行反射操作时,依据存储的反射信息访问对应的地址。

在RTTR中,类型元数据存储在rttr::detail::class_data、rttr::detail::type_data中,

struct RTTR_LOCAL class_data
{class_data(get_derived_info_func func, std::vector<type> nested_types):   m_derived_info_func(func),m_nested_types(nested_types),m_dtor(create_invalid_item<destructor>()){}get_derived_info_func       m_derived_info_func;std::vector<type>           m_base_types;std::vector<type>           m_derived_types;std::vector<rttr_cast_func> m_conversion_list;std::vector<property>       m_properties;std::vector<method>         m_methods;std::vector<constructor>    m_ctors;std::vector<type>           m_nested_types;destructor                  m_dtor;
};
struct RTTR_LOCAL type_data
{type_data* raw_type_data;type_data* wrapped_type;type_data* array_raw_type;std::string name;string_view type_name;std::size_t get_sizeof;std::size_t get_pointer_dimension;impl::create_variant_func create_variant;impl::get_base_types_func get_base_types; // FIXME: this info should not be stored, its just temporarily,// thats why we store it as function pointerenumeration_wrapper_base*  enum_wrapper;impl::get_metadata_func    get_metadata;impl::create_wrapper_func  create_wrapper;impl::get_class_data_func  get_class_data;bool is_valid;RTTR_FORCE_INLINE bool type_trait_value(type_trait_infos type_trait) const RTTR_NOEXCEPT { return m_type_traits.test(static_cast<std::size_t>(type_trait)); }type_traits m_type_traits;
};

3.1 生成rttr::detials::type_data

当第一次调用type::get()函数时,会生成对应的类型元数据,

template<typename T>
RTTR_INLINE type type::get() RTTR_NOEXCEPT
{using non_ref_type = typename std::remove_cv<typename std::remove_reference<T>::type>::type;return detail::create_or_get_type<non_ref_type>();
}template<typename T>
RTTR_LOCAL RTTR_INLINE enable_if_t<is_complete_type<T>::value, type>
create_or_get_type() RTTR_NOEXCEPT
{// when you get an error here, then the type was not completely defined// (a forward declaration is not enough because base_classes will not be found)using type_must_be_complete = char[ sizeof(T) ? 1: -1 ];(void) sizeof(type_must_be_complete);static const type val = create_type(get_registration_manager().add_item(make_type_data<T>()));return val;
}

 从中可以看出,rttr::type实际上时对类型数据的一种引用。

3.2 注册类型信息数据

rttr::registration实际上时借助于函数对象rttr::registration::bind完成构造函数的注册,

template<typename Class_Type>
template<typename F, typename acc_level, typename Tp>
registration::bind<detail::ctor_func, Class_Type, F, acc_level> registration::class_<Class_Type>::constructor(F func, acc_level level)
{using namespace detail;static_assert(is_functor<F>::value,"No valid accessor for invoking the constructor provided!");static_assert(std::is_same<return_func, typename method_type<F>::type>::value,"For creating this 'class type', please provide a function pointer or std::function with a return value.");return {create_if_empty(m_reg_exec), func};
}
template<typename Class_Type, typename F, typename acc_level>
class registration::bind<detail::ctor_func, Class_Type, F, acc_level> : public registration::class_<Class_Type>
{
//...    
public:bind(const std::shared_ptr<detail::registration_executer>& reg_exec, F func):   registration::class_<Class_Type>(reg_exec), m_reg_exec(reg_exec), m_func(func){m_reg_exec->add_registration_func(this);}template<typename... Args>registration::class_<Class_Type> operator()(Args&&... args){m_ctor = create_custom_constructor(m_func, std::forward<Args>(args)...);return registration::class_<Class_Type>(m_reg_exec);}
//...
}
registration_executer::~registration_executer()
{for (auto&& item : m_list){item.second();}
}

至于,属性、方法等类型元数据的注册,原理类似,可参照对应代码。

3.3 生成对象

rttr::type调用存储的构造器,完成对象的实例化。

variant type::create(vector<argument> args) const
{auto& ctors = m_type_data->get_class_data().m_ctors;for (const auto& ctor : ctors){if (detail::compare_with_arg_list::compare(ctor.get_parameter_infos(), args))return ctor.invoke_variadic(std::move(args));}return variant();
}

网络资料

Reflectionicon-default.png?t=N7T8https://en.wikipedia.org/wiki/Reflection_%28computer_programming%29

The C++ Extensions for Reflection icon-default.png?t=N7T8https://en.cppreference.com/w/cpp/experimental/reflect

RTTRicon-default.png?t=N7T8https://www.rttr.org/QMetaObjecticon-default.png?t=N7T8https://doc.qt.io/qt-5/qmetaobject.html

yazi-web icon-default.png?t=N7T8https://github.com/kaifamiao/yazi-web.git

Boost Hana icon-default.png?t=N7T8https://www.boost.org/doc/libs/1_80_0/libs/hana/doc/html/index.html

Boost PRF icon-default.png?t=N7T8https://www.boost.org/doc/libs/master/doc/html/boost_pfr.html

 An Introduction to Reflection in C++icon-default.png?t=N7T8https://blog.csdn.net/qq_26221775/article/details/138768568?spm=1001.2014.3001.5501

FreeCAD: C++ Generic Factory Method inteface adviceicon-default.png?t=N7T8https://forum.freecad.org/viewtopic.php?p=24221&hilit=BaseClass#p24221

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

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

相关文章

C++ STL概念之 迭代器

什么是迭代器 迭代器&#xff08;Iterator&#xff09;是一个在容器中访问元素的对象&#xff0c;提供了一种方法来顺序访问容器中的元素&#xff0c;而无需暴露容器的底层表示。 或者说 行为像指针一样的类型。可能是指针也可能是被类封装的指针&#xff0c;不关注容器底层细…

搭建内网穿透服务(frp)

搭建内网穿透服务(frp&#xff09; 一、为什么 在平时工作当中&#xff0c;我们经常会遇到需要将自己本地的服务暴露在公网上&#xff0c;方便与他人进行接口对接、或者进行演示等等&#xff0c;虽然有一些免费的内网穿透服务&#xff0c;但是大都很不稳定或者带宽太低&#x…

让调用者自己干活的特殊线程池

让调用者自己干活的特殊线程池 1. 相关背景 单元测试时, 我们的某些业务代码可能是在线程池中运行的&#xff0c;可能会出现各种不一致的情况。 这时候可以hack一下, 创建一个调用者直接执行的线程池&#xff0c;避免干扰; 2. 实现代码 import java.util.concurrent.*;// 让…

【永洪BI】资源导出

路径&#xff1a;管理系统>资源部署>资源导出 1.页面介绍 选择左侧面板中的管理系统&#xff0c;点击资源部署&#xff0c;选择资源导出&#xff0c;进入资源导出页面。 【名称】导出的 jar 文件的名称&#xff0c;必填项。 【描述】导出的 jar 文件中包含的描述信息…

Gateway基本配置的参数以及yml示例

Spring Cloud Gateway作为API网关&#xff0c;可以通过配置文件来定义路由规则、过滤器和相关参数。 参入如下&#xff1a; routes: 定义了一组路由规则&#xff0c;每个路由规则包含了路由的ID、目标URI、断言集合和过滤器集合。 id: 路由的唯一标识符&#xff0c;用于区分不同…

华为昇腾310B1平台视频解码失败[ERROR] Send frame to vdec failed, errorno:507018

目录 1 [ERROR] Send frame to vdec failed, errorno:507018 2 bug解决尝试1 3 bug解决尝试2 4 最终解决方法 参考文献&#xff1a; 1 [ERROR] Send frame to vdec failed, errorno:507018 某项目中的代码运行报错 [ERROR] Send frame to vdec failed, errorno:507018 Ac…

Linux系统 -目录结构与配网

目录的特点 Windows中有C盘、D盘等&#xff0c;每个都是一个根系统是个多根系统 Linux中只有一个根是个单根系统 Linux-目录存储的内容 1、/root&#xff1a;管理员的家目录 2、/home&#xff1a;存储普通用户家目录的目录/3、/tmp&#xff1a;临时目录&#xff0c;这个目录存储…

linux系统管理面试题

用户管理&#xff1a; 1. 如何在Linux中创建一个新用户并设置密码&#xff1f; 在Linux中创建一个新用户并设置密码&#xff0c;可以使用以下步骤&#xff1a; 打开终端或命令行界面。使用root权限登录或使用sudo命令获取管理员权限。运行以下命令来创建新用户&#xff08;将…

了解 Robot Framework :接口自动化测试教程!

开源自动化测试利器&#xff1a;Robot Framework Robot Framework 是一个用于实现自动化测试和机器人流程自动化&#xff08;RPA&#xff09;的开放源代码框架。它由一个名为 Robot Framework Foundation 的组织得到推广&#xff0c;得到了多家领军企业在软件开发中的广泛应用。…

运营商三要素核验接口如何对接

运营商三要素核验接口又叫运营商手机号三要素验证接口、运营商手机号实名认证接口、运营商手机号三要素核验接口&#xff0c;指的是输入姓名、身份证号码及手机号&#xff0c;通过运营商数据库实时校验此三项是否匹配。那么运营商三要素核验接口如何对接呢&#xff1f; 首先我…

Java SE入门及基础(51) Queue 接口 比较器接口

目录 Queue 接口 1. 特性描述 Queue 接口常用方法 2. LinkedBlockingQueue 用法示例 3. PriorityQueue 用法示例 思考&#xff1a;如果 PriorityQueue 队列中存储的是对象&#xff0c;会怎么排序&#xff1f; 比较器接口 1. 比较器接口的作用 2. Comparable 接口 示…

【设计模式】JAVA Design Patterns——Abstract Factory(抽象工厂模式)

&#x1f50d;目的 提供一个用于创建相关对象家族的接口&#xff0c;而无需指定其具体类 &#x1f50d;解释 真实世界例子 要创建一个王国&#xff0c;我们需要具有共同主题的对象。精灵王国需要精灵国王、精灵城堡和精灵军队&#xff0c;而兽人王国需要兽人国王、兽人城堡和兽…

项目路由分模块A模块B模块C......模块N使用

路由分模块原因&#xff1a; vue框架中会有router文件&#xff0c;但是路由文件下只有一个路由文件&#xff0c;在实际项目开发中会有多人负责多模块的情况&#xff0c;若都在一个文件内编辑路由名称&#xff0c;就相当于是机房里的数据线&#xff0c;会很乱七八糟&#xff0c;…

1. go语言初识(一)

本篇博客涉及到的内容&#xff1a;变量和常量、iota常量生成器、类型转换 变量&#xff08;Variables&#xff09;和常量&#xff08;Constants&#xff09; 变量&#xff08;Variables&#xff09; 1. 定义变量 在Go中&#xff0c;可以使用’var‘关键字来声明一个变量&…

【十大排序算法】----选择排序(详细图解分析+实现,小白一看就会)

目录 一&#xff1a;选择排序——原理 二&#xff1a;选择排序——分析 三&#xff1a;选择排序——实现 四&#xff1a;选择排序——优化 五&#xff1a;选择排序——效率 一&#xff1a;选择排序——原理 选择排序的原理&#xff1a;通过遍历数组&#xff0c;选出该数组…

使用Docker配置深度学习环境——以diffusers为例

Docker的其他信息可以在我的网站上找到&#xff0c;这里假设安装完成了&#xff0c;直接上手。 git clone 仓库地址打开docker目录&#xff0c;找到目标版本&#xff1a; sudo docker build diffusers-pytorch-cuda如果失败&#xff0c;尝试使用换源&#xff1a; sudo nano …

GPT-4o 炸裂发布!你竟然还没用上?(附详细教程)

今天AI界的爆炸新闻非chatgpt-4o莫属&#xff0c;从早上到现在随处可见的文章推送&#xff0c;视频推送。 大家或多或少都有耳闻了&#xff0c;今天主要讲一讲我们普通人到底怎么用&#xff1f;如果不氪金行不行&#xff1f;我就想体验一下可不可以&#xff1f;带着问题往下看 …

提升写作效率的秘密武器:一个资深编辑的AI写作体验

有句话说:“写作是一项你坐在打字机前流血的工作。”而如今,各类生成式软件的涌现似乎打破了写作这一古老的艺术形式壁垒。过去,作家们独自在书桌前冥思苦想,如今,一款名为“玲珑AI工具”的ai写作助手正悄然改变着文案写作行业的创作生态,成为提升写作效率的秘密武器。 在传统…

【数据结构】图和基本算法

文章目录 1. 图的基本概念1.1 图本身的定义1.2 相关概念 2. 图的存储结构2.1 邻接矩阵2.2 邻接表 3. 图的遍历3.1 广度优先遍历&#xff08;BFS&#xff09;3.2 深度优先遍历&#xff08;DFS&#xff09; 4. 最小生成树4.1 Kruskal算法4.2 Prim算法 5. 最短路径5.1 单源最短路径…

【Linux】基础命令:进程、网络

systemctl命令 控制内置服务 systemctl start | stop | status | enable | disable 服务名 start | stop开启关闭&#xff0c;status状态&#xff0c;enable | disable开启关闭开机自启 date命令 查看系统时间 date [-d] [格式化字符串] date -d “1 day” %Y-%m-%d 修改时区…