如何使用Boost Describe将包含枚举成员的结构体转换为JSON?
解决Boost Describe结构体转JSON时枚举成员的序列化问题
Boost Describe官方提供的结构体自动转JSON示例,在处理包含非嵌套枚举成员的结构体时会失效——原代码没有实现枚举类型到JSON的序列化逻辑。我们可以通过添加针对枚举类型的tag_invoke重载,结合Boost Describe对枚举的描述能力来解决这个问题。
修改后的完整代码
#include <boost/describe.hpp> #include <boost/json.hpp> #include <boost/mp11.hpp> #include <iostream> #include <map> #include <type_traits> #include <vector> namespace app { // 处理结构体/类的序列化逻辑(保留原示例代码) template <class T, class D1 = boost::describe::describe_members< T, boost::describe::mod_public | boost::describe::mod_protected>, class D2 = boost::describe::describe_members< T, boost::describe::mod_private>, class En = std::enable_if_t<boost::mp11::mp_empty<D2>::value && !std::is_union<T>::value>> void tag_invoke(boost::json::value_from_tag const &, boost::json::value &v, T const &t) { auto &obj = v.emplace_object(); boost::mp11::mp_for_each<D1>( [&](auto D) { obj[D.name] = boost::json::value_from(t.*D.pointer); }); } // 新增:处理枚举类型的序列化逻辑 template <class E, class = std::enable_if_t<boost::describe::has_describe_enumerators<E>::value>> void tag_invoke(boost::json::value_from_tag const&, boost::json::value& v, E const& e) { // 将枚举值转换为对应的字符串名称 char const* name = boost::describe::enum_to_string(e, nullptr); v = name ? name : "unknown_enum_value"; } enum E { e1, e2 }; BOOST_DESCRIBE_ENUM(E, e1, e2); struct A { int x; int y; E e; }; BOOST_DESCRIBE_STRUCT(A, (), (x, y, e)) } // namespace app int main() { app::A a{1, 2, app::e1}; std::cout << boost::json::value_from(a) << std::endl; }
关键修改说明
- 新增的枚举序列化重载:通过
boost::describe::has_describe_enumerators判断类型是否为已描述的枚举,再用boost::describe::enum_to_string将枚举值转换为对应的字符串,最终写入JSON值。 - 必须确保枚举类型已通过
BOOST_DESCRIBE_ENUM宏完成描述,这样Boost Describe才能获取枚举值与名称的映射关系。
编译运行后,输出结果为:{"x":1,"y":2,"e":"e1"},实现了包含枚举成员的结构体到JSON的正确转换。
内容的提问来源于stack exchange,提问作者Koija
相关产品推荐
相关产品推荐

