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";// 保存到jsonj["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保存到jsonj = u.to_string();}};
}int main()
{nlohmann::json j ;uri u = "http://baidu.com";// 保存到jsonj["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进阶使用(三)使用basic_json模板类
nlohmann::json是非常好用的一个json开源解析库.nlohmann/json的源码是基于C++11标准写的,整个源码就是一个文件 nlohmann/json.hpp,引用非常方便. 关于 ...
- hutol json null值没了_JSON数据处理框架Jackson精解第一篇-序列化与反序列化核心用法...
Jackson是Spring Boot默认的JSON数据处理框架,但是其并不依赖于任何的Spring 库.有的小伙伴以为Jackson只能在Spring框架内使用,其实不是的,没有这种限制.它提供了很 ...
- 苹果新的编程语言 Swift 语言进阶(二)--基本数据类型
一 . 常量和变量 Swift语言 对常量和变量的声明进行了明白的区分 Swift语言的常量类型比C 语言的constants类型更加强大,语义更加明白. 常量和变量的差别是常量在设置或初始化后 ...
- c++中nlohmann json的使用
文章目录 一.json.hpp库下载及安装 1.1 开源地址及引入方法 1.2 demo程序测试 二.nlohmann json基本操作 2.1 由basic value创建json 2.2 由jso ...
- 石川es6课程---11、json
石川es6课程---11.json 一.总结 一句话总结: ` 感觉更方便了一点,增加了一些简写 ` key-value 一样时可以简写:console.log({ a,b}}) ` 里面函数可以简写 ...
- C++ nlohmann/json 的主要用法
文章目录 前言 准备工作 引用头文件: 主要用法: 一.声明与构造 1 纯粹声明 2 内容构造 二.解析与序列化 字符串 解析 序列化 文件:// 比如有文件 c:\rankings.json,其内容 ...
- Quartz.Net进阶之二:关于触发器的更多信息
Quartz.Net进阶之二:关于触发器的更多信息 原文:Quartz.Net进阶之二:关于触发器的更多信息 与作业一样,触发器相对容易使用,但是在您可以充分利用Quartz.NET之前,确实需要了解 ...
- mysql 进阶(二)
##mysql 进阶(二) ###多表联合查询 什么是多表联合查询 前面所讲的查询语句都是针对一个表的,但是在关系型数据库中,表与表之间是有联系的,所以在实际应用中,经常使用多表查询.多表查询就是同时 ...
- C++ 之 nlohmann::json 一个不错的json库
前言 最近在搞一个C++项目,用到了json和类的相互转化.但是c++没有反射,也没有像java一个方便的插件,没法办只能自己搞一个了.网上找了一下,发现nlohmann::json不错.已经运用到实 ...
- 【C++】C++库nlohmann / json的使用
nlohmann / json for Modern C++ 前言 一.nlohmann/json库简述 1. 概述 2. 优点 3. 配置 二.nlohmann/json库的基本操作 1. 读取 / ...
最新文章
- 计算机网络技术专业毕业大作业答案,计算机网络技术大作业考核要求A卷
- gdb调试问题Missing separate debuginfos, use: debuginfo-install
- 50种优化数据库的方法
- spring mvc 返回html 乱码,解决springmvc使用ResponseBody注解返回json中文乱码问题
- PHP base64数据与图片的互相转换
- 求4个数字组成的不重复三位数,Python简洁解法
- xshell无法显示汉字
- 华为linux用什么浏览器,Linux系统浏览器最受用户欢迎前十排名
- AM3352 uboot中对NandFlash坏块的处理
- java poi Excel加密文件导出和下载
- js控制wmplayer
- 解决问题:cv::Exception,位于内存位置 0x000000D2956FE120 处
- Linux系统卸载virtualbox,如何在Mac上卸载VirtualBox
- android系统开发 AP 和 BP 简要说明
- matlab 模拟 峰信号
- signature=f380c172efecdd0f7b9329d16d09ca45,Virtual Identity Signs in Online Communication
- 用网线实现两台电脑之间的大文件传输(使用电脑备份)
- EL表达式写三目运算
- CSU1020-真三国无双-模拟
- LeetCode每日一题——Day1