3

この単純なクラスをシリアル化しようとしています:

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 へのポイティング。これを有効にするブーストシリアル化の方法は、追加することです

#include <boost/uuid/uuid_serialize.hpp>

しかし、これはそのままではシリアルには機能しません。穀物の文書によると

シリアル アーカイブは std::ostream または std::istream オブジェクトのいずれかで動作します。

だから私は定義されているが運がないヘッダーを追加しようとしました

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

2 に答える 2

5

これは穀物の 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_
于 2014-11-19T05:53:20.007 に答える
1

事実

シリアル アーカイブは、std::ostream または std::istream オブジェクトのいずれかで動作します。

IOストリーミング演算子(>>、<<)を使用していることを(まったく)意味しません。それは単なるアーカイブの実装です。

Free 関数を実装してserialize、Cereal にタイプを知らせる必要があります。に示す実装を再利用できるはずですuuid_serialize.hpp。おそらく、あなたは単にすべきです

  • これらの定義を cereal 名前空間 (できれば) または boost::uuids 名前空間 (将来競合する可能性があります) に移動して、ADL がそれらを見つけられるようにします。
  • UUID を単純なバイト配列として扱うのが最善です (AFAIRboost::uuids::uuidは POD データ型です)
于 2014-11-18T08:13:57.870 に答える