我有以下枚举
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中,但这种接缝不是很聪明(如果必须这样做,我必须改变很多东西)。
谢谢和问候
答案 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
不起作用;我测试了它