【问题标题】:How to serialize a boost::uuid with cereal如何用谷物序列化 boost::uuid
【发布时间】:2015-01-15 07:57:19
【问题描述】:

尝试序列化这个简单的类:

class Data
{
public:
    Data();
    Data(boost::uuids::uuid id);

    Data(const Data&) = delete;
    Data& operator=(const Data&) = delete;

    inline boost::uuids::uuid getGuid() { return guid; }

    template <class Archive>
    void serialize(Archive & ar)
    {
        ar(guid);
    }

private:
    boost::uuids::uuid guid;
};

但我收到此错误消息

error C2338: Trying to serialize an unserializable type with an output archive. 

指向 uuid。启用此功能的 boost 序列化方法是添加

#include <boost/uuid/uuid_serialize.hpp>

但这不适用于开箱即用的谷物。谷物文件说

谷物档案在 std::ostream 或 std::istream 对象上运行。

所以我尝试在已定义但没有运气的地方添加标题

#include <boost/uuid/uuid_io.hpp>

【问题讨论】:

  • Boost 不是麦片,所以,你应该只用麦片写boost::uuid 的序列化。

标签: c++ boost boost-uuid cereal


【解决方案1】:

这适用于谷物 JSON 档案。我还在评论中包含了一种用于二进制存档的方法。

#ifndef CEREAL_TYPES_BOOST_UUID_
#define CEREAL_TYPES_BOOST_UUID_

#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <boost/lexical_cast.hpp>

namespace cereal
{
    template <class Archive> inline
        void save(Archive& ar, boost::uuids::uuid const& uuid)
    {
        std::string val = boost::lexical_cast<std::string>(uuid);

        ar(val);

        // Other approach, probably better for binary
        //ar(make_size_tag(static_cast<size_type>(uuid.size())));
        //for (auto it = uuid.begin(), end = uuid.end(); it != end; ++it)
        //  ar(*it);
    }

    template <class Archive> inline
        void load(Archive& ar, boost::uuids::uuid& uuid)
    {
        std::string val;

        ar(val);
        uuid = boost::lexical_cast<boost::uuids::uuid>(val);

        // Other approach, probably better for binary
        //size_type size;
        //ar(make_size_tag(size));

        //for (auto it = uuid.begin(), end = uuid.end(); it != end; ++it) {
        //  uint8_t val;
        //  ar(val);
        //  *it = val;
        //}
    }
} // namespace cereal

#endif // CEREAL_TYPES_BOOST_UUID_

【讨论】:

    【解决方案2】:

    事实

    谷物档案在 std::ostream 或 std::istream 对象上运行。

    并不(根本)暗示它使用 IO 流操作符(>>、archive 实现。

    您必须实现免费功能 serialize 才能让 Cereal 知道您的类型。您应该能够重用uuid_serialize.hpp 中显示的实现。您可能应该简单地

    • 将这些定义移动到谷物命名空间(最好)或 boost::uuids 命名空间(将来可能会发生冲突),以便 ADL 找到它们
    • 最好将 UUID 视为简单的字节数组(AFAIR boost::uuids::uuid 是一种 POD 数据类型)

    【讨论】:

    • @kittikun 我不得不想知道,这个答案是否有点糟糕(你现在没有投票?)
    • 是的,很抱歉,我想也许答案没有直接回答问题。无论如何,我投票支持你
    • @kittikun 谢谢。老实说,我认为你应该接受你自己的答案,因为“它解决了你的问题”,而你可以直接投票(“这个答案很有用”)?
    猜你喜欢
    • 1970-01-01
    • 2012-06-01
    • 2020-06-20
    • 2018-04-30
    • 2017-06-07
    • 2018-03-12
    • 2016-08-21
    • 2017-02-19
    • 2017-09-03
    相关资源
    最近更新 更多