强大的 boost::variant 序列化

Posted

技术标签:

【中文标题】强大的 boost::variant 序列化【英文标题】:Robust boost::variant serialization 【发布时间】:2011-11-08 15:21:54 【问题描述】:

我在我的应用程序中使用boost::variantboost::serialize。序列化模块内置了对序列化变体的支持,因此:

boost::variant<int,double> u(3.14);

// Do something with u;

// Serialize
oa << u;

有效。但是,我的问题是序列化不健壮。根据我的应用程序的编译方式,变体的元素可能会发生变化。目前,序列化模块似乎只是嵌入了“活动”变体类型的索引;如果变体更改为 boost::variant&lt;double,string&gt;,则会出现问题。

任何人都可以提出改进方法,以便序列化/反序列化工作,以便已序列化的类型是boost::variant 的模板参数。 (因此,在上述情况下,boost::variant&lt;int,double&gt; u(3.14) 可以反序列化为 boost::variant&lt;double,std::string&gt;。我知道这可能需要我提供其他信息,例如类型的字符串化形式。

【问题讨论】:

为什么要更改变体的元素?你通常不希望你的文件格式规范像那样改变。 通常我会同意,但是,程序本身是一个数值模拟。模拟类被大量模板化,有几百万种可能的组合。显然,我无法将它们全部实例化为可执行文件。鉴于我的用户群都是自编译的,使用变体来保存支持的实例是合理的。 【参考方案1】:

这样的现成机制如何运作?例如,如果您将boost::variant&lt;int,double&gt; 更改为boost::variant&lt;int,std::string&gt; 并且无法再容纳双打,该怎么办?抛出异常?

如果您想要类似的东西,我想您必须自己编写它来涵盖您预期的情况并符合您对“稳健”的定义。

您还可以构建一些文件升级逻辑...例如,您的程序的每个版本 N 都保留了 (N-1, N-2...) 结构定义的旧副本,这样您就可以能够编写可用于提供升级遇到的旧文件的例程。

但实际上,最好在将程序发布到野外之前,尽可能在第一时间就设置好文件格式!尤其是编码用户意图的数据(如果版本无法识别它们,可以丢弃并重新计算实际上只是缓存的派生结构)。

【讨论】:

以上是关于强大的 boost::variant 序列化的主要内容,如果未能解决你的问题,请参考以下文章

如何返回由 boost::variant 返回类型中包含的类型的子集组成的 boost::variant

Boost::Variant 和其中的 function_types:如何将函数放入 Boost::variant?

boost::variant:递归向量类型的奇怪行为

std::variant 是不是提供类似于 boost::variant<>::types 的功能?

使用 boost::mpl 获取 boost::variant 的类型索引

boost::variant 与 bool 和 string