boost::archive::binary_oarchive 如何处理枚举?
How does a boost::archive::binary_oarchive handle an enum?
我有以下枚举
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,但这种接缝不是很智能(如果必须这样做,我必须更改很多东西)。
谢谢和问候
与 Boost Serialization 一样,要自定义用户定义类型的处理,您需要实现 自定义点,它是成员 serialize/load/save
或免费的函数 serialize/load/save
(由 ADL 查找)。
由于成员函数不是枚举的选项,因此您需要为您的类型提供重载,例如 serialize
。可悲的是,除了内置基本类型的预定义重载之外,没有办法获得 "better" 的通用实现。
这是接近的结果(但它不起作用¹):
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));
}
} }
We can take the shortcut of "binary_object" serialization as we know by definition that enums have integral values as their underlying type, which makes them POD.
鉴于这个——不幸的——限制,也许最好的方法是手动调用 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
符合预期。您可以在 serialize
实现中使用 make_binary_object
包装器,它将透明地处理序列化和反序列化。
请参阅:Boost Serialization Wrappers Boost 文档
¹ 出于类似原因,BOOST_IS_BITWISE_SERIALIZABLE(Example)
将不起作用;我测试了
我有以下枚举
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,但这种接缝不是很智能(如果必须这样做,我必须更改很多东西)。
谢谢和问候
与 Boost Serialization 一样,要自定义用户定义类型的处理,您需要实现 自定义点,它是成员 serialize/load/save
或免费的函数 serialize/load/save
(由 ADL 查找)。
由于成员函数不是枚举的选项,因此您需要为您的类型提供重载,例如 serialize
。可悲的是,除了内置基本类型的预定义重载之外,没有办法获得 "better" 的通用实现。
这是接近的结果(但它不起作用¹):
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));
}
} }
We can take the shortcut of "binary_object" serialization as we know by definition that enums have integral values as their underlying type, which makes them POD.
鉴于这个——不幸的——限制,也许最好的方法是手动调用 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
符合预期。您可以在 serialize
实现中使用 make_binary_object
包装器,它将透明地处理序列化和反序列化。
请参阅:Boost Serialization Wrappers Boost 文档
¹ 出于类似原因,BOOST_IS_BITWISE_SERIALIZABLE(Example)
将不起作用;我测试了