4

我注意到反射是其他语言的开发人员发现 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看看它是如何公平的。

4

3 回答 3

1

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

于 2010-03-18T18:21:39.253 回答
1

与其强制我使用某种运行时反射方法,我宁愿拥有编译时反射功能,我可以使用它来生成我需要的信息。

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

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

于 2010-03-18T19:51:51.643 回答
0

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

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

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

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

于 2010-03-18T19:06:39.160 回答