当前位置:   article > 正文

c++11:nlohmann::json进阶使用(三)使用basic_json模板类_修改nlohmann json gbk 中文

修改nlohmann json gbk 中文

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();
		}
	};
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

显然上面的adl_serializer<uri>类只适用于nlohmann::json类和uri类之间的转换,如果你的项目中即用到了nlohmann::json也用到了nlohmann::ordered_json都需要对uri进行序列化和反序列化,上面的类对于nlohmann::ordered_json就不能用了。简单的办法就是再写一个与上面的adl_serializer<uri>差不多的类来实现nlohmann::ordered_jsonuri之间的转换.
能不能写一个adl_serializer<uri>类解决问题呢?

basic_json

那就要用到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();
		}
	};
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

上面的方式只是解决了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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66

以上代码在Visual Studio 2015下编译测试通过

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/601200
推荐阅读
相关标签
  

闽ICP备14008679号