赞
踩
nlohmann::json是非常好用的一个json开源解析库.nlohmann/json
的源码是基于C++11标准写的,整个源码就是一个文件 nlohmann/json.hpp
,引用非常方便。
关于nlohmann/json
的基本使用官网(https://github.com/nlohmann/json)上有比较详细的介绍。这里不再赘述,本文主要是介绍在nlohmann/json
的基本使用之外一些我在使用 nlohmann/json
用到的一些扩展功能和重要但不太被了解的特性。
我的上一篇博客里解决了第三方数据类型序列化和反序列化的问题
《c++11:nlohmann::json进阶使用(二)应用adl_serializer解决第三方数据类型(such as uri)的序列化和反序列化》
下面是解决问题的实现代码:
namespace nlohmann {
template <>
struct adl_serializer<uri> {
static uri from_json(const json& j) {
return{ j.template get<std::string>() };
}
static void to_json(json& j, const uri &u) {
j = u.to_string();
}
};
}
显然上面的adl_serializer<uri>
类只适用于nlohmann::json
类和uri
类之间的转换,如果你的项目中即用到了nlohmann::json
也用到了nlohmann::ordered_json
都需要对uri
进行序列化和反序列化,上面的类对于nlohmann::ordered_json
就不能用了。简单的办法就是再写一个与上面的adl_serializer<uri>
差不多的类来实现nlohmann::ordered_json
和uri
之间的转换.
能不能写一个adl_serializer<uri>
类解决问题呢?
那就要用到basic_json
模板类了.
我们通常用到的nlohmann::json
其实是模板类nlohmann::basic_json
的特例化实现。nlohmann::ordered_json
也是,解决上面的问题需要用nlohmann::basic_json
代替nlohmann::son
作为json对象参数类型。
只要将nlohmann::json
类型参数 改为 nlohmann::basic_json
,将to_json,from_json
都改为模板函数,就可以实现对nlohmann::json
,nlohmann::ordered_json
的同时支持
如下:
namespace nlohmann {
template <>
struct adl_serializer<uri> {
// 只有一个参数的模板函数,参数用于定义map类型
template<template<typename, typename, typename...> class ObjectType>
static uri from_json(const basic_json<ObjectType>& j) {
return{ j.template get<std::string>() };
}
template<template<typename, typename, typename...> class ObjectType>
static void to_json(basic_json<ObjectType>& j, const uri &u) {
j = u.to_string();
}
};
}
上面的方式只是解决了basic_json
模板类第一个模板参数ObjectType
可变的问题。如果要实现对basic_json
模板类的完全支持,to_json,from_json
的模板参数就需要定义basic_json
的所有模板参数
参照json.hpp
中的宏定义方式如下实现:
nlohmann_json_test4.cpp
#include <iostream> #include "uri/uri.hh" #include "nlohmann/json.hpp" #ifndef _BASIC_JSON_TPL_PARAMS_ #define _BASIC_JSON_TPL_PARAMS_ \ ObjectType, ArrayType, StringType, BooleanType, \ NumberIntegerType, NumberUnsignedType, NumberFloatType, \ AllocatorType, JSONSerializer, BinaryType #endif // !_BASIC_JSON_TPL_PARAMS_ #ifndef _BASIC_JSON_TPL_PARAM_DECL_ #define _BASIC_JSON_TPL_PARAM_DECL_ \ template<typename U, typename V, typename... Args> class ObjectType = std::map, \ template<typename U, typename... Args> class ArrayType = std::vector, \ class StringType = std::string, class BooleanType = bool, \ class NumberIntegerType = std::int64_t, \ class NumberUnsignedType = std::uint64_t, \ class NumberFloatType = double, \ template<typename U> class AllocatorType = std::allocator, \ template<typename T, typename SFINAE = void> class JSONSerializer = nlohmann::adl_serializer, \ class BinaryType = std::vector<std::uint8_t> #endif // !_BASIC_JSON_TPL_PARAM_DECL_ #ifndef _BASIC_JSON_TPL_DECLARATION_ #define _BASIC_JSON_TPL_DECLARATION_ template<_BASIC_JSON_TPL_PARAM_DECL_> #endif // !_BASIC_JSON_TPL_DECLARATION_ #ifndef _BASIC_JSON_TPL_ #define _BASIC_JSON_TPL_ \ nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, \ NumberIntegerType, NumberUnsignedType, NumberFloatType, \ AllocatorType, JSONSerializer, BinaryType> #endif // ! _BASIC_JSON_TPL_ namespace nlohmann { template <> struct adl_serializer<uri> { // 支持basic_json所有模板参数可定义 _BASIC_JSON_TPL_DECLARATION_ static uri from_json(const _BASIC_JSON_TPL_& j) { return{ j.template get<std::string>() }; } _BASIC_JSON_TPL_DECLARATION_ static void to_json(_BASIC_JSON_TPL_& j, const uri &u) { j = u.to_string(); } }; } int main() { nlohmann::json j ; uri u = "http://baidu.com"; // 保存到json j["uri"] = u; // 从json中读取uri对象 uri u2 = j["uri"].get<uri>(); std::cout << "u2:" << u2.to_string() << std::endl; }
以上代码在Visual Studio 2015下编译测试通过
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。