c++11:nlohmann::json进阶使用应用adl_serializer解决第三方数据类型(such as uri)的序列化和反序列化
Posted 10km
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c++11:nlohmann::json进阶使用应用adl_serializer解决第三方数据类型(such as uri)的序列化和反序列化相关的知识,希望对你有一定的参考价值。
nlohmann::json是非常好用的一个json开源解析库.nlohmann/json
的源码是基于C++11标准写的,整个源码就是一个文件 nlohmann/json.hpp
,引用非常方便。
关于nlohmann/json
的基本使用官网(https://github.com/nlohmann/json)上有比较详细的介绍。这里不再赘述,本文主要是介绍在nlohmann/json
的基本使用之外一些我在使用 nlohmann/json
用到的一些扩展功能和重要但不太被了解的特性。
uri
ben-zen/uri-library是我在网上找到的一个C++11写的URI解析工具,用于URI字符串解析为一个uri
对象,只需要一个头文件uri.hh
,引用非常方便。
在我的项目中我使用uri
而不是普通的std::string
来保存一个URI地址,但是在将uri
对象保存到 nlohmann::json
时遇到了麻烦。
我当然希望如下就能简单的将一个uri对象保存到 nlohmann::json
nlohmann_json_test3.cpp
#include <iostream>
#include "uri/uri.hh"
#include "nlohmann/json.hpp"
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;
实际上直接这样写是不行的,因为uri
是个第三方类型,并不是nlohmann::json
支持的基本数据类型,所以nlohmann::json
并不知道如何对它进行序列化和反序列化,所以编译就会报错。
如果你对nlohmann/json
略有了解就知道,按照nlohmann/json
官网的基本用法,对于nlohmann/json
不支持的自定义数据类型开发者需要自己实现to_json(BasicJsonType& j, const T& value)
和from_json(const BasicJsonType& j, T& value)
函数,nlohmann/json
才会知道怎么对这个类型进行序列化和反序列化。
那么我自己实现to_json(BasicJsonType& j, const uri& value)
和from_json(const BasicJsonType& j, uri& value)
不就可以了么?
void to_json(BasicJsonType& j, const uri& value)
j = value.to_string();
void from_json(const BasicJsonType& j, uri& value)
value = j.get<std::string>();
呵呵,也是不合适的,因为仔细查看源码uri/uri.hh
源码,发现uri
这个对象是没有默认构造函数的。
如果没有默认构造函数,也就无法有构造默认uri
对象,上面to_json(BasicJsonType& j, const uri& value)
的输入参数从何而来呢?
adl_serializer
再仔细看看nlohmann/json
官方文档,发现人家对于这种没有默认构造函数,也非用户自定义类型的第三方数据类型也提供了相应解决方案,就是 adl_serializer
模板类。
我们需要做的就是为uri
实现提供 nlohmann::adl_serializer
模板类的特例化实现:
上面代码nlohmann_json_test3.cpp中如下增加 adl_serializer<uri>
就可以正常编译运行了:
#include <iostream>
#include "uri/uri.hh"
#include "nlohmann/json.hpp"
namespace nlohmann
// uri 没有默认构造函数,要采用下面的方式提供序列化和反序列化方法,否则json::get<uri>()不能调用
template <>
struct adl_serializer<uri>
static uri from_json(const json& j)
// 反序列化
// 从json中获取std::string,调用uri的构造函数
// uri(std::string const &uri_text, scheme_category category = scheme_category::Hierarchical,
// query_argument_separator separator = query_argument_separator::ampersand)
// 将std::string转为uri对象
return j.template get<std::string>() ;
static void to_json(json& j, const uri &u)
// 序列化
// 调用 uri::to_string()函数将uri对象转为std::string保存到json
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;
以上是关于c++11:nlohmann::json进阶使用应用adl_serializer解决第三方数据类型(such as uri)的序列化和反序列化的主要内容,如果未能解决你的问题,请参考以下文章
c++11:nlohmann::json进阶使用应用adl_serializer解决第三方数据类型(such as uri)的序列化和反序列化
C语言进阶—— 程序环境和预处理 ( 坚持总会有收获!!!)