C++反射之检测struct或class是否实现指定函数

目录

1.引言

2.检测结构体或类的静态函数

3.检测结构体或类的成员函数

3.1.方法1

3.2.方法2


1.引言

        诸如Java, C#这些语言是设计的时候就有反射支持的。c++没有原生的反射支持。并且,c++提供给我们的运行时类型信息非常少,只是通过typeinfo提供了有限的一些支持。这一点点支持其实连类型名都无法打印好。更别说去检测一个结构体或类是否具有实现指定函数。

        通过编写模板代码和std::enable_ifrequires(C++20)表达式,你可以根据某个类型是否拥有特定的成员函数或方法来启用或禁用某些代码。这种方法不会直接告诉你一个类型是否实现了某个函数,但它允许你根据类型的能力编写条件编译的代码。如:

template<typename T, typename = void>  
struct has_func_impl : std::false_type {};  template<typename T>  
struct has_func_impl<T, std::void_t<decltype(std::declval<T&>().func())>> : std::true_type {};  template<typename T>  
constexpr bool has_func_v = has_func_impl<T>::value;  // 使用示例  
struct MyClass {  void func() {}  
};  static_assert(has_func_v<MyClass>); // 成功

2.检测结构体或类的静态函数

C++之std::declval-CSDN博客

1)通过编写一个模板结构和它的特化版本来检测是否存在某个成员函数。

2)使用std::declval来在编译时模拟对成员函数的调用。

3)如果调用成功,则特化版本继承自std::true_type,否则继承自std::false_type

代码如下:

#define HAS_MEMBER_EX(member)\
template<typename T, typename... Args> struct has_member_ex_##member{\
private:\template<typename U> \static auto Check(int) -> decltype(U::member(std::declval<Args>()...), std::true_type()); \template<typename U> \static std::false_type Check(...); \
public:\enum { value = std::is_same<decltype(Check<T>(0)), std::true_type>::value }; \
}; \HAS_MEMBER_EX(getDataSize)

测试代码:

//A1具有静态getDataSize()函数
class A1{
public:static int getDataSize() {return 100;}
};//A2只有成员函数getDataSize()函数
class A2{
public:int getDataSize() {return 100;}
};//A3无函数
class A3{};int main()
{constexpr bool bA1 = has_member_ex_getDataSize<A1>::value; //输出: trueconstexpr bool bA2 = has_member_ex_getDataSize<A2>::value; //输出: falseconstexpr bool bA3 = has_member_ex_getDataSize<A3>::value; //输出: falsereturn 0;
}

3.检测结构体或类的成员函数

3.1.方法1

也是利用std::declval结合decltype来判断是否具有某个函数,代码如下:

#define HAS_NON_STATIC_MEMBER_EX(member)\
template<typename T, typename... Args> struct has_non_static_member_ex_##member{\
private:\template<typename U> \static auto Check(int) -> decltype(std::declval<U>()().member(std::declval<Args>()...), std::true_type()); \template<typename U> \static std::false_type Check(...); \
public:\enum { value = std::is_same<decltype(Check<T>(0)), std::true_type>::value }; \
}; \HAS_NON_STATIC_MEMBER_EX(getDataSize)

  测试代码:

//A1,A2,A3同上,省略int main()
{constexpr bool bA1 = has_non_static_member_ex_getDataSize<A1>::value; //输出: trueconstexpr bool bA2 = has_non_static_member_ex_getDataSize<A2>::value; //输出: trueconstexpr bool bA3 = has_non_static_member_ex_getDataSize<A3>::value; //输出: falsereturn 0;
}

        我们使用std::declval<U>()::member()来尝试“调用”该类型的member成员函数(而不需要创建一个实际的对象)。如果这行代码在编译时有效(即U类型有一个无参数且返回类型为可推导的member成员函数),那么我们就特化Check()std::true_type;否则,我们保持其默认实现为std::false_type

3.2.方法2

实现代码如下:

#define HAS_NON_STATIC_MEMBER_EX1(R, member) \
template<typename T> struct has_non_static_member_ex1_##member{ \
private:\template<typename Y, Y y>	\class Helper;	\template<typename U = T>	\constexpr static bool has##member(...) {\return false;\}\template<typename U = T>\constexpr static bool has##member(Helper<R (U::*)()const, &U::member>*) {\return true;\}\
public:\static const bool value = has##member<T>(nullptr);\
};\HAS_NON_STATIC_MEMBER_EX1(int, getDataSize)

测试代码同上。

推荐阅读

C++之std::declval

C++模板函数重载规则细说

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

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

相关文章

leetcode刷题(5): STL的使用

文章目录 56. 合并区间解题思路c实现 55. 跳跃游戏解题思路c 实现 75. 颜色分类解题思路c 实现 36 下一个排列解题思路c 实现 56. 合并区间 题目: 以数组 intervals 表示若干个区间的集合&#xff0c;其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间&a…

Linux(openEuler、CentOS8)企业内网samba服务器搭建(Windows与Linux文件共享方案)

本实验环境为openEuler系统<以server方式安装>&#xff08;CentOS8基本一致&#xff0c;可参考本文) 目录 知识点实验1. 安装samba2. 启动smb服务并设置开机启动3. 查看服务器监听状态4. 配置共享访问用户5. 创建共享文件夹6. 修改配置文件7. 配置防火墙8. 使用windows…

Hypack 2024 简体中文资源完整翻译汉化已经全部完成

Hypack 2024 简体中文资源完整翻译汉化已经全部完成 Hypack 2024&#xff0c;资源汉化共翻译11065条。毕竟涉及测绘、水文、疏浚等专业术语太多&#xff0c;翻译有很多理解不正确的地方&#xff0c;望各位专业人员指正。 压缩包内包含Hypack 2024、Hypack 2022、Hypack 2021、…

Autoxjs 实践-Spring Boot 集成 WebSocket

概述 最近弄了福袋工具&#xff0c;由于工具运行中&#xff0c;不好查看福袋结果&#xff0c;所以我想将福袋工具运行数据返回到后台&#xff0c;做数据统计、之后工具会越来越多&#xff0c;就弄了个后台&#xff0c;方便管理。 实现效果 WebSocket&#xff1f; websocket是…

Qt应用开发(拓展篇)——图表 QChart

一、前言 QChart是一个图形库模块&#xff0c;它可以实现不同类型的序列和其他图表相关对象(如图例和轴)的图形表示。要在布局中简单地显示图表&#xff0c;可以使用QChartView来代替QChart。此外&#xff0c;线条、样条、面积和散点序列可以通过使用QPolarChart类表示为极坐标…

Python的奇妙之旅——回顾其历史

我们这个神奇的宇宙里&#xff0c;有一个名叫Python的小家伙&#xff0c;它不仅聪明&#xff0c;而且充满活力。它一路走来&#xff0c;从一个小小的编程语言成长为如今全球最受欢迎的编程语言之一。今天&#xff0c;我们就来回顾一下Python的历史&#xff0c;看看它如何从一个…

字体设计_西文字体设计(英文字体设计)

一 西文字体设计基础知识 设计目标和历史成因 设计目标&#xff1a;让眼睛看着舒服的字体 那什么样的字体让眼睛看着舒服呢&#xff1f; 让眼睛看着舒服的字体造型其实是我们记忆里的手写体、自然造型。 所以就能理解西文字体为什么同一笔画&#xff0c;有的地方粗有的地方…

DDPM与扩散模型

很早之前就新建了一个专栏从0开始弃坑扩散模型 ,但发了一篇文章就没有继续这一系列&#xff0c;在这个AIGC的时代&#xff0c;于是我准备重启这个专栏。 整个专栏的学习顺序可以见这篇汇总文章 这是本专栏的第一章 目录 引言生成模型的发展历程 引言 扩散模型( Diffusion Mode…

52页 | 2024大型语言模型行业图谱研究报告(免费下载)

【1】关注本公众号&#xff0c;转发当前文章到微信朋友圈 【2】私信发送 【2024大型语言模型行业图谱研究报告】 【3】获取本方案PDF下载链接&#xff0c;直接下载即可。 如需下载本方案PPT原格式&#xff0c;请加入微信扫描以下方案驿站知识星球&#xff0c;获取上万份PPT解…

STC8增强型单片机开发——库函数

一、使用库函数点灯 导入库函数。 下载STC8H的库函数&#xff1a;&#x1f4ce;STC8G-STC8H-LIB-DEMO-CODE_2023.07.17_优化版.zip 来到库函数的目录下&#xff0c;拷贝以下文件&#xff1a; Config.hType_def.hGPIO.hGPIO.c 新建项目&#xff0c;将拷贝的4个文件放到项目目录…

WEB基础--JDBC操作数据库

使用JDBC操作数据库 使用JDBC查询数据 五部曲&#xff1a;建立驱动&#xff0c;建立连接&#xff0c;获取SQL语句&#xff0c;执行SQL语句&#xff0c;释放资源 建立驱动 //1.加载驱动Class.forName("com.mysql.cj.jdbc.Driver"); 建立连接 //2.连接数据库 Stri…

【Android】Room数据库的简单使用方法

Room数据库的使用方法 目录 1、添加Room数据库的依赖2、Entity——定义实体类 2.1 定义主键——PrimaryKey2.2 字段注解——ColumnInfo 3、Dao——定义数据访问对象4、Database——数据库 4.1 通过回调观察数据库是否创建成功 5、使用时注意点6、编写异步 DAO 查询 6.1 写异步…

【CSS】认识CSS选择器及各选择器对应的用法

目录 一、什么是CSS&#xff1f; 二、CSS 选择器 1. 标签选择器 2. 类选择器 3. ID选择器 4. 通配符选择器 5. 复合选择器 一、什么是CSS&#xff1f; CSS(Cascading Style Sheet)&#xff0c;层叠样式表。它与 HTML&#xff08;超文本标记语言&#xff09;一起使用&am…

Django-新冠疫情数据分析系统-67684

目 录 摘要 1 绪论 1.1 研究背景 1.2论文结构与章节安排 2 新冠疫情数据分析系统系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1 数据增加流程 2.2.2 数据修改流程 2.2.3 数据删除流程 2.3 系统功能分析 2.3.1 功能性分析 2.3.2 非功能性分析 2.4 系统用例分析…

2024.5.8 2.二叉树的最大深度 (简单)

给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;3 示例 2&#xff1a; 输入&#xff1a;root [1,null,2] 输…

批量图片重命名及汇总

又一堆图片文件需要处理... 源文件分布&#xff1a; 有N个文件夹&#xff0c;每个文件夹下又有M个子文件夹&#xff0c;每个子文件夹下有X张图片。 例如文件夹A下有子文件夹A1,A2,A3&#xff0c;子文件夹A1下有图片a-1,a-2,a-3...... 处理目标&#xff1a; 1、将所有图片汇…

五月最新流行音乐网,整点干货(10个网站)听歌就要自由!

随着互联网的迅猛发展&#xff0c;音乐产业也迎来了前所未有的变革。如今&#xff0c;我们无需再依赖传统的唱片店或电台&#xff0c;就能轻松接触到来自世界各地的音乐。而“最新流行音乐网”正是这一变革的产物&#xff0c;为广大音乐爱好者提供了一个探索音乐潮流的新天地。…

将大概的流程具体还是看源码

之前看源码的时候呢没有文字整理&#xff0c;想来还是写一个大概的流程吧&#xff0c;具体是无法用文字描述 spring源码真的yyds&#xff0c;数据结构 反射 父子类 接口…玩得溜到飞起 博大精深呐 后期不断喜欢ing&#xff01; springApplication.run方法 获取了一个Configu…

无刷电机和有刷电机的区别

无刷电机和有刷电机的区别 无刷电机的定子上绕着线圈&#xff0c;线圈通常是成对出现的&#xff0c;通过控制电路为每一对线圈按照一定顺序输入电流&#xff0c;就可以产生旋转的磁场 它还有一个永磁体转子&#xff0c;现在多采用高磁能级的稀土铷铁硼材料&#xff0c;体积更小…

DBdoctor产品介绍

基本信息 DBdoctor是聚好看科技股份有限公司自主研发的一款数据库内核级性能诊断工具&#xff0c;首次将eBPF技术聚焦在了数据库领域&#xff0c;一分钟内定位数据库性能问题并给出优化建议&#xff0c;实现数据库性能诊断百倍提效。 免费下载 请在PC端打开以下链接&#x…