在C ++中内省结构定义?

时间:2011-02-13 19:05:13

标签: c++

所以我正在研究一种文件格式,用于存储在某种范围内定义的结构化数据。最简单的例子就像浮动值随着时间的推移,但我正在设计它以允许每个点的多个维度和任意数据。我想将数据的结构存储在文件头中,因为它将允许一些简洁的功能。

起初我以为我会让用户使用类的层次结构来构建他们的数据结构,所以你可以这样做:

pf_type data = record(PF_DOUBLE) (
                  record("position")(
                     field("xp") &
                     field("yp") &
                     field("zp")) &
                  record("velocity")(
                     field("xv") &
                     field("yv") &
                     field("zv")) &
                  record("acceleration")(
                     field("xa") &
                     field("ya") &
                     field("za")));

在C:

中等同于这样的东西
struct {
   struct position {
       double xp,yp,zp;
   }
   struct velocity {
       double xv,yv,zv;
   }
   struct acceleration {
       double xa,ya,za;
   }
}

这并不可怕,但它仍然要求用户在读/写数据时单独定义一个实际使用的c结构。

我认为如果他们可以定义一个他们传递给我的库的常规c-struct并且我在其上进行内省以获取写入该文件的信息,那就太好了。虽然我不知道在C ++中是否可以远程实现类似的东西。我的想法是它可能正在使用一些模板元编程魔法,但它会非常混乱。所以我想我会向那些了解C ++的人提出一些想法,而不是我。

3 个答案:

答案 0 :(得分:7)

不是完全你正在寻找什么,但可能是一个非常好的灵感来源,Google's Protobufs。它们采用的方法与您在问题中讨论的方法略有不同。使用protobuf,首先在.proto文件中描述您的数据结构,然后使用protobuf编译器(protoc)编码用于几种不同语言之一的样板代码,包括C ++。

代码化代码完全能够反映.proto文件中定义的结构,以及最优化的protobuf是串行化二进制数据以通过线路发送。显然,你会付出一点点性能,但它会给你带来一些非常高质量的反射,而简单访问的性能并不是那么高。

基本上,您图书馆的客户可以通过您填写的protobuf。通过直接给您打电话,或通过网络电话。

答案 1 :(得分:3)

模板机器太原始了,无法合理地做这种事情。在我看来,更好的选择是有一个单独的易于编辑和易于解析的文件来描述数据结构,然后从该定义生成所需的C ++代码。

然而,在C ++中编写代码生成器很烦人,因为C ++ I / O,解析,格式化和字符串操作不是最理想的,我的建议是使用Python或其他very high level language作为该部分。

然后可以将所有内容放入具有适当依赖关系的Makefile中(即,如果描述文件更改,则重新生成C ++文件),因此构建仍然是自动的。

使用“普通”C ++文件而不是模板技巧将使您的生活变得更加轻松(编译时,错误消息,编译器与硬核模板不兼容,支持调试生成的代码)。

答案 2 :(得分:0)

Boost.Fusion有一些巧妙的技巧可以为C ++带来编译时反射,在你的情况下,我认为你最感兴趣的是BOOST_FUSION_ADAPT_STRUCT

如果您希望添加补充重载,例如可以从字符串中获取字段。你需要增加一些互补的能力。

整个事情可以用宏和模板完成......但我宁愿坚持使用protobuf;)