让nlohmann json支持std::wstring和嵌套结构的序列化与反序列化
nlohmann json是一个star很高的C++ json解析库。
要让nlohmann json支持某个类型T,只要给这个类型T实现一个偏特化的struct adl_serializer<T>即可。adl_serializer是这个库里面针对泛型T预定义的适配器。
对于std::optional,也是要增加偏特化。
template <typename T> struct adl_serializer<std::optional<T>> { static void to_json(json& j, const std::optional<T>& opt) { if (opt == std::nullopt) { j = nullptr; } else { j = *opt; } } static void from_json(const json& j, std::optional<T>& opt) { if (j.is_null()) { opt = std::nullopt; } else { opt = j.get<T>(); } } };
而嵌套结构,本身就支持的。使用预定义的宏NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE,可以免去自己针对每个类型T要实现其from_json/to_json函数。
下面是一个例子,适用于VC++。里面UTF-8和UTF-16的转换可以自行换成其他的实现方式。
#define _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING #include <string> #include <codecvt> #include <locale> #include <nlohmann/json.hpp> using json = nlohmann::json; namespace nlohmann { template <> struct adl_serializer<std::wstring> { static void to_json(json& j, const std::wstring& str) { std::wstring_convert<std::codecvt_utf8<wchar_t>> converter; j = converter.to_bytes(str); } static void from_json(const json& j, std::wstring& str) { std::wstring_convert<std::codecvt_utf8<wchar_t>> converter; str = converter.from_bytes(j.get<std::string>()); } }; } namespace ns { struct Address { std::wstring country; std::wstring province; std::wstring city; }; NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Address, country, province, city) struct Person { std::wstring name; Address address; int age; }; NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Person, name, address, age) } int main(int argc, char* argv[], char* envp) { ns::Person p{ L"匿名", { L"中国", L"湖北", L"武汉" }, 60 }; json j = p; const auto s = j.dump(); auto p2 = j.template get<ns::Person>(); return 0; }