Как сериализовать повышение :: uuid с хлопьями

Попытка сериализации этого простого класса:

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>

2

Решение

Это работало с зерновыми архивами 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_
4

Другие решения

Дело в том, что

зерновые архивы работают либо с объектом std :: ostream, либо с std :: istream.

(вовсе) не подразумевает, что он использует потоковые операторы ввода-вывода (>>, <<). Вот только архив реализация.

Вам придется реализовать бесплатную функцию serialize сообщить Cereal о вашем типе. Вы должны быть в состоянии повторно использовать реализацию, показанную в uuid_serialize.hpp, Скорее всего, вы должны просто

  • переместите эти определения в пространство имен злаков (предпочтительно) или в пространство имен boost :: uuids (может возникнуть конфликт в будущем), чтобы ADL мог их найти
  • лучше всего рассматривать UUID как простые массивы байтов (AFAIR boost::uuids::uuid это тип данных POD)
1