【问题标题】:boost serialization and doubles提升序列化和双打
【发布时间】:2011-09-07 02:35:48
【问题描述】:

我正在尝试使用 boost 序列化库将一个类序列化为一个字符串,并且我的类中包含几个双成员变量。

下面是我用来序列化的代码:

#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/string.hpp>

std::stringstream ss;
boost::archive::text_oarchive oa(ss);
oa << mPoint;

这是我的 Point 类中的序列化方法:

friend class boost::serialization::access;

template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
    if (version > 0)
    {
        ar & mLatitude;
        ar & mLongitude;
    }
}

当我序列化为字符串时,boost 似乎没有像我预期的那样处理双精度到字符串的转换(似乎存在舍入问题)。稍微研究一下,看起来其他人也报告了同样的行为。我也了解与将双精度数转换为字符串相关的精度相关问题,反之亦然,以及这如何导致问题。

奇怪的是,我不明白的是,当我使用 stringstream 本身并将双精度重定向到流时,或者当我使用 boost 的 lexical_cast 函数从 stringstream.str 转换时,这似乎不会发生() 回双。在发现 boost 有自己的序列化/反序列化类之前,我实际上已经使用 stringstream 和 lexical_cast 调用编写了自己的类,并且它没有问题。我真的希望我不必放弃序列化库并回到我以前的状态。希望只有一些设置/特征/等。我不见了。

【问题讨论】:

  • 明显而愚蠢的建议是将其序列化为二进制数据,而不是字符串?也许这就是解决方案?同样,如果这很容易,您可能已经这样做了... :) 如果不是很长时间没有答案并且我很想找到解决方案,我不会提供我的建议。 :)
  • boost 的 lexical_cast 具有复杂的逻辑来适当地设置流的精度 - 请参阅 boost.org/doc/libs/1_46_1/boost/detail/lcast_precision.hpp
  • 你能举一个正确往返和不正确往返的值的例子吗?

标签: c++ serialization boost floating-point boost-serialization


【解决方案1】:

您可以尝试在序列化之前强制您的流使用科学格式的浮点数:

ss << std::scientific;

boost 库似乎正确设置了精度,但似乎没有设置格式。或者,您可以认为派生和覆盖用于保存和/或加载浮点数的逻辑,而不会丢弃库的其余部分 - 开始 here

看起来还有 work in progress 支持无限等。

【讨论】:

  • 我还修改了类以将我的数据元素表示为 float 而不是 double 看起来做同样的事情,至少解决了我在序列化方面的问题。
【解决方案2】:

这并不能直接回答Boost.Serialization 的问题,但可能是一种解决方法。

根据上述问题,我不清楚您是否需要字符串表示。如果您正在寻找跨平台表示(二进制或其他),请考虑使用protobuf,它确实支持编码doubles。

http://code.google.com/apis/protocolbuffers/docs/proto.html#scalar

【讨论】:

    猜你喜欢
    • 2012-09-24
    • 2013-08-25
    • 2018-12-22
    • 2012-11-25
    • 1970-01-01
    • 1970-01-01
    • 2014-04-22
    • 2010-10-14
    • 1970-01-01
    相关资源
    最近更新 更多