关于 std::type_info 中的反射扩展的总体感觉是什么?

发布于 2024-08-25 15:35:23 字数 1011 浏览 5 评论 0原文

我注意到反射是其他语言的开发人员发现 C++ 中非常缺乏的一项功能。对于某些应用程序,我真的明白为什么!如果您有反思,那么编写诸如 IDE 自动完成之类的东西会容易得多。当然,如果我们拥有序列化 API,世界将会变得更加容易。

另一方面,C++ 的主要原则之一是不要为不使用的东西付费。这是完全有道理的。这就是我喜欢 C++ 的地方。

但我想到可能会有妥协。为什么编译器不向 std::type_info 结构添加扩展?不会有运行时开销。二进制文件最终可能会更大,但这可能是一个简单的编译器开关来启用/禁用,说实话,如果您真的关心空间节省,您可能会禁用异常和 RTTI。

有些人引用了模板的问题,但编译器已经很乐意为模板类型生成 std::type_info 结构。

我可以想象像 -fenable-typeinfo-reflection 这样的 g++ 开关可能会变得非常流行(并且像 boost/Qt/etc 这样的主流库可以很容易地进行检查以生成使用它的代码,如果存在的话,在在这种情况下,最终用户将受益,而无需花费比按下开关更多的成本)。我不认为这是不合理的,因为像这样的大型可移植库已经依赖于编译器扩展。

那么为什么这种情况不更常见呢?我想我错过了一些东西,这有什么技术问题?

编辑: 只是一些关于膨胀论点的指标:

我研究了一个相当大的 Qt 项目(大约 45,000 LoC)并测量了元对象的大小。我觉得这是一个合理的指标,因为 Qt moc 系统是一个相当详尽的反射系统(类型、函数、枚举、成员和一些 Qt 特定概念,如“属性”)。 总共有 67 个元对象,所以数量不是微不足道的,但也不算疯狂,总共有 5479 字节。然而,几乎所有这些都是 32 字节或更小(最大的是 1427 字节)。考虑到现代编译器即使是最简单的程序也会生成 4K 以上的二进制文件,这些数字并不算离谱)。不过我很乐意看到类似的东西应用于 STL 来看看它如何公平。

I've noticed that reflection is one feature that developers from other languages find very lacking in c++. For certain applications I can really see why! It is so much easier to write things like an IDE's auto-complete if you had reflection. And certainly serialization APIs would be a world easier if we had it.

On the other side, one of the main tenets of c++ is don't pay for what you don't use. Which makes complete sense. That's something I love about c++.

But it occurred to me there could be a compromise. Why don't compilers add extensions to the std::type_info structure? There would be no runtime overhead. The binary could end up being larger, but this could be a simple compiler switch to enable/disable and to be honest, if you are really concerned about the space savings, you'll likely disable exceptions and RTTI anyway.

Some people cite issues with templates, but the compiler happily generates std::type_info structures for template types already.

I can imagine a g++ switch like -fenable-typeinfo-reflection which could become very popular (and mainstream libs like boost/Qt/etc could easily have a check to generate code which uses it if there, in which case the end user would benefit with no more cost than flipping a switch). I don't find this unreasonable since large portable libraries like this already depend on compiler extensions.

So why isn't this more common? I imagine that I'm missing something, what are the technical issues with this?

EDIT: Just a few metrics re-the bloat argument:

I've looked at a fairly large Qt project (about 45,000 LoC) and measures the size of the metaObjects. I feel this is a reasonable metric because the Qt moc system is a fairly exhaustive reflection system (types, functions, enumerations, members and a few Qt specific concepts like "properties"). There were 67 metaobjects total, so not a trivial amount but nothing crazy, which added up to 5479 bytes. However almost all of them were 32-bytes or less (the largest being 1427 bytes). Considering that modern compilers produce binaries of upwards of 4K for even the simplest program, this these numbers aren't outrageous). Though I'd love to see something like this applied to the STL to see how it fairs.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

凤舞天涯 2024-09-01 15:35:23

通常,使用反射表明软件设计很差劲;正确使用接口和多态性足以完成您使用反射所做的几乎所有事情。如果在 std::type_info 中添加额外的信息,确实会导致程序膨胀。模板的问题不是你不能从它们生成 std​​::type_info ,而是你可以获得类型的爆炸,因此模板的每个实例化都会产生另一个你需要的 std::type_info 对象。您使用编译器开关的建议并没有真正的帮助或意义......首先,标准永远不会指定编译器开关,因为那将是特定于实现的,但假设它是这样做的......什么如果您想对来自禁用反射的库的类使用反射,会发生什么情况?如果大多数库禁用了反射(它们可能会这样做),那么它将严重限制该功能的实用性,如果大多数库没有禁用它,那么您将在不使用它的情况下为其付费。

Usually the use of reflection is indicative of poor software design; proper use of interfaces and polymorphism is sufficient to do pretty much whatever you would do with reflection. If one were to add extra information into std::type_info, it would indeed lead to program bloat. The issue with templates is not that you cannot generate std::type_info from them, but rather that you can get an explosion of types, and so every instantiation of the template results in yet another std::type_info object that you would need. Your suggestion of using a compiler switch doesn't really help or make sense... first of all, the standard would never specify a compiler switch, because that would be implementation-specific, but assuming it were to do so... what would happen if you wanted to use reflection with a class that came from a library for which reflection was disabled? If most libraries disabled reflection -- which they probably would -- then it would severely limit the utility of that feature, and if most libraries didn't disable it, then you would be paying for it without using it.

驱逐舰岛风号 2024-09-01 15:35:23

我宁愿拥有编译时反射功能,我可以用它来生成我需要的信息,而不是强加给我某种运行时反射方法。

这样我就不必为我实际上不使用的信息付费,并且可以使用元编程来根据需要生成接口代码,而无需额外的预构建步骤或一些复杂的声明性 EDSL。

Caspin 此处提到了一种可能的方法。老实说,我很惊讶这个主题似乎从未作为包含在 C++ 中的提案被推动。

Instead of having a certain runtime reflection approach forced on me, i'd rather have compile time reflection capabilities that i could use to generate the information i need.

That way i wouldn't have to pay for information i don't actually use and could use meta-programming to generate interfacing code as needed without additional pre-build steps or some elaborate declaritive EDSL.

Caspin mentioned one possible approach here. To be honest, i am surprised that the subject seems to have never been pushed as a proposal for inclusion in C++.

故事与诗 2024-09-01 15:35:23

也许 C/C++ 中的多种类型使得灵活的反射编程变得困难。能够处理任何基元类型的假设数据库或序列化接口将需要 [unsigned] int、short、[long] long、char、float、[long] double、其数组、相关函数等的特殊情况。到名称修饰器的接口。

我不认为这是一个很好的理由。几年前我在Boost MPL中写了一个反射式SQL接口,很麻烦。如果使用“本地”设施,情况会更好、更容易。

我认为大多数人通过额外的预处理来实现反射,例如 Apple 的 Mach Interface Generator 以及 GNU 和 Microsoft 的类似工具。

比 C++ 缺乏支持更令我惊讶的是,在推动竞争的新兴语言中,例如 D 和(无论如何在精神上)Go。

Perhaps the multitude of types in C/C++ makes flexible reflective programming difficult. An hypothetical database or serializing interface capable of handling any primitive types would need special cases for [unsigned] int, short, [long] long, char, float, [long] double, arrays thereof, functions relating to, etc. It would amount to an interface to the name mangler.

Not that I think that's a good reason. I wrote a reflective SQL interface in Boost MPL several years ago, and it was troublesome. It would have been much nicer and easier with a "native" facility.

I think most people achieve reflection with additional preprocessing, such as Apple's Mach Interface Generator and similar tools at GNU and Microsoft.

More surprising to me than the lack of support in C++ is that in the up-and-coming languages that drive competition, such as D and (in spirit anyway) Go.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文