参考资料:https://zhuanlan.zhihu.com/p/388454455
参考github地址:https://github.com/netcan/config-loader
最近在做一个可配置系统的参数设置工具时,由于参数数量众多,包含多层树结构,并且参数之间还会有相互关系。
配置参数的读写,从技术选型上有ini,xml,json。由于ini原生不支持树结构,需要根据需要将父节点的option作为子节点的section,配置文件可读性变差。xml由于属性和元素分开的形式,不适合直接转为c++定义的树状结构。所有最终选择了json。
要想用c++实现一个通用的json文件序列化和反序列化工具,反射是绕不开的。c++语言原生不支持反射,因此要通过一些编程技巧实现。在查阅资料过程中发现了configloader,clone学习过程中发现该代码库目前仅实现了json文件的读取,写入还没有实现,因此,狗尾续貂,实现了json文件的写入,勉强是满足了笔者的项目需求。
使用宏包装的结构体定义方法,包含了编译期字段数量计算,每个字段的名称和变量的封装,每个字段是否是最后一个字段判断(用来序列号json时最后一个字段不加“,”)。
#define DEFINE_SCHEMA(st, ...) \
struct st { \
template struct FIELD; \
static constexpr size_t _field_count_ = GET_ARG_COUNT(__VA_ARGS__); \
static constexpr decltype(#st) _schema_name_ = #st; \
EXPAND(PASTE(REPEAT_, GET_ARG_COUNT(__VA_ARGS__)) (FIELD_EACH, 0, __VA_ARGS__)) \
} \
#define FIELD_EACH(i, arg)