boost :: archive :: binary_oarchive如何处理枚举?

时间:2015-04-06 22:04:27

标签: c++ boost enums

我有以下枚举

enum Example : uint8_t {
   First = 1,
   Second = 2,
 };

和一个字符串流:

std::stringstream stream;
boost::archive::binary_oarchive ar(stream);

现在我注意到了,如果我序列化一个枚举:

ar << Example::First;

boost序列化4字节(在本例中为0x01,0x00,0x00,0x00)位而不是uint8_t所需的8位(0x01)。 有什么方法可以避免这种情况吗?我的意思是,我知道我可以将这个枚举投入到uint8_t中,但这种接缝不是很聪明(如果必须这样做,我必须改变很多东西)。

谢谢和问候

1 个答案:

答案 0 :(得分:3)

与Boost序列化一样,为了自定义用户定义类型的处理,您需要实现自定义点,它是成员serialize/load/save或自由函数{{1} (由ADL查询)。

由于成员函数不是枚举的选项,因此您需要为您的类型提供例如serialize/load/save的重载。遗憾的是,没有办法让它的通用实现比内置基元类型的预定义重载“更好”。

接下来会是什么(但它不起作用):

serialize
  

我们可以采用“binary_object”序列化的快捷方式,因为根据定义我们知道枚举具有整数值作为其基础类型,这使得它们成为POD。

鉴于此 - 不幸 - 限制,也许最好的方法是手动拨打namespace boost { namespace serialization { template <typename Ar, typename T> typename std::enable_if<std::is_enum<T>::value, void>::type serialize(Ar& ar, T& e, unsigned) { ar & boost::serialization::make_binary_object(&e, sizeof(e)); } } } ,如下所示:

<强> Live On Coliru

make_binary_object

打印

#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/serialization/binary_object.hpp>
#include <boost/serialization/serialization.hpp>
#include <iostream>
#include <sstream>

using boost::serialization::make_binary_object;

enum class Example : uint8_t {
    First  = 1,
    Second = 2,
};

int main() {

    std::stringstream stream;
    boost::archive::binary_oarchive ar(stream, boost::archive::no_header);

    auto data = Example::First;
    ar << make_binary_object(&data, sizeof(data));

    std::cout << "Size: " << stream.str().size() << "\n";
}

正如所料。您可以在Size: 1 实现中使用make_binary_object包装器,它将透明地处理序列化和反序列化。

请参阅Boost文档中的Boost Serialization Wrappers


¹出于类似的原因,serialize不起作用;我测试了它