我希望能够自省一个c++类的名称,内容(即成员及其类型)等。这里我说的是原生c++,而不是托管c++,托管c++有反射。我意识到c++使用RTTI提供了一些有限的信息。哪些附加库(或其他技术)可以提供这些信息?
当前回答
你可以通过Boost::Hana库中的BOOST_HANA_DEFINE_STRUCT实现很酷的静态反射功能。 Hana非常通用,不仅适用于您所想到的用例,还适用于许多模板元编程。
其他回答
在我的c++生涯中,我知道的两个类似反射的解决方案是:
1)使用RTTI,如果你能够从一个“对象”基类派生所有的类,它将为你提供一个引导来构建类似反射的行为。该类可以提供一些方法,如GetMethod, GetBaseClass等。至于这些方法是如何工作的,你需要手动添加一些宏来装饰你的类型,这些宏在幕后创建类型的元数据,为GetMethods等提供答案。
2)如果你可以访问编译器对象,另一个选择是使用DIA SDK。如果我没记错的话,这允许您打开pdbs,其中应该包含c++类型的元数据。也许足够做你想做的事了。例如,本页展示了如何获取类的所有基类型。
这两种解决方案都有点难看!没有什么比c++更能让你欣赏c#的奢华了。
祝你好运。
Ponder是一个c++反射库,用于回答这个问题。我考虑了这些选择,决定自己做一个,因为我找不到一个符合我所有要求的。
虽然这个问题有很好的答案,但我不想使用大量宏,也不想依赖Boost。Boost是一个很棒的库,但也有很多小型定制的c++ 0x项目,它们更简单,编译时间更快。能够从外部装饰一个类也有好处,比如包装一个不支持c++ 11的c++库。它是CAMP的分支,使用c++ 11,不再需要Boost。
我也想要一匹小马,但小马不是免费的。: - p
http://en.wikibooks.org/wiki/C%2B%2B_Programming/RTTI是你将得到的。像您所考虑的反射——运行时可用的完整描述性元数据——在默认情况下c++中不存在。
c++中还有另一个用于反射的新库,叫做RTTR(运行时类型反射,参见github)。
该接口类似于c#中的反射,并且不需要任何RTTI。
c++的开箱即用不支持反射。这很可悲,因为它让防御性测试变得很痛苦。
有几种进行反思的方法:
使用调试信息(不可移植)。 在代码中加入宏/模板或其他源代码方法(看起来很难看) 修改编译器(如clang/gcc)以生成数据库。 使用Qt moc方法 提高反映 精确平坦的反射
第一个链接看起来最有希望(使用mod的clang),第二个讨论了一些技术,第三个是使用gcc的不同方法:
http://www.donw.org/rfl/ https://bitbucket.org/dwilliamson/clreflect https://root.cern.ch/how/how-use-reflex
现在有一个c++反射工作组。查看c++ 14 @ CERN的新闻:
https://root.cern.ch/blog/status-reflection-c
编辑13/08/17:
自最初的帖子以来,已经有了一些关于反思的潜在进展。下面提供了关于各种技术和状态的更多细节和讨论:
简要介绍静态反射 静态的反射 静态反射设计
然而,在不久的将来,在c++中实现标准化的反射方法看起来并不有希望,除非社区对支持c++中的反射有更多的兴趣。
下面是基于上次c++标准会议反馈的当前状态:
对反思建议的反思
编辑13/12/2017
Reflection看起来正在向c++ 20或更高版本的TSR迈进。然而运动是缓慢的。
镜子 镜像标准方案 镜纸 包括反射在内的元编程
编辑15/09/2018
TS草案已送交国家机构进行投票。
文本可以在这里找到:https://github.com/cplusplus/reflection-ts
编辑11/07/2019
反射TS已完成功能,并将于2019年夏天接受评论和投票。
元模板编程方法将被更简单的编译时代码方法所取代(在TS中没有反映出来)。
TS草案截至2019-06-17
编辑10/02/2020
这里有一个在Visual Studio中支持反射TS的请求:
https://developercommunity.visualstudio.com/idea/826632/implement-the-c-reflection-ts.html
作者David Sankel谈论TS:
http://cppnow.org/history/2019/talks/ https://www.youtube.com/watch?v=VMuML6vLSus&feature=youtu.be
2020年3月17日
反思正在取得进展。“2020-02布拉格ISO c++委员会旅行报告”的报告可以在这里找到:
https://www.reddit.com/r/cpp/comments/f47x4o/202002_prague_iso_c_committee_trip_report_c20_is/
关于c++ 23正在考虑的细节可以在这里找到(包括关于反射的简短部分):
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0592r4.html
2020年6月4日
Jeff Preshing发布了一个名为“胶合板”的新框架,它包含了一种运行时反射机制。详情请点击这里:
https://preshing.com/20200526/a-new-cross-platform-open-source-cpp-framework/
到目前为止,这些工具和方法看起来是最完善和最容易使用的。
2020年7月12日编辑
叮当实验反射叉:https://github.com/lock3/meta/wiki
有趣的反射库,使用clang工具库提取信息进行简单的反射,不需要添加宏:https://github.com/chakaz/reflang
2021年2月24日编辑
一些额外的clang工具方法:
https://github.com/Celtoys/clReflect https://github.com/mlomb/MetaCPP
2021年8月25日编辑
youtube https://www.youtube.com/watch?v=60ECEc-URP8上的ACCU在线演讲也很值得一听,它讨论了当前对标准的建议和基于clang的实现。
See:
https://github.com/lock3/meta,分支论文/p2320 编译器资源管理器:https://cppx.godbolt.org/编译器版本使用p2320中继。
推荐文章
- cplusplus.com给出的错误、误解或坏建议是什么?
- 找出质数最快的算法是什么?
- 访问Handlebars.js每次循环范围之外的变量
- c++枚举类可以有方法吗?
- 格式化IO函数(*printf / *scanf)中的转换说明符%i和%d之间的区别是什么?
- 将析构函数设为私有有什么用?
- main()中的Return语句vs exit()
- 为什么c#不提供c++风格的'friend'关键字?
- 获取当前正在执行的方法的名称
- 在函数的签名中添加关键字
- 我如何在Visual Studio中预处理后看到C/ c++源文件?
- 为什么在标准容器中使用std::auto_ptr<>是错误的?
- 用比较double和0
- 保护可执行文件不受逆向工程的影响?
- 在c++中字符串前面的“L”是什么意思?