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. 读取 / ...
最新文章
- 读一个文件的java程序_java 读文件的几种方法(一)
- python基础教程教材-Python3零基础教材电子书合集
- 2022年美国大学生数学建模竞赛——Problem C:交易策略
- 阮一峰react demo代码研究的学习笔记 - demo 3 debug
- POLYCOM RMX2000 激活与初始化 信令板卡初始化
- 虚拟网关与正规网关的区别
- iPhone13最新外观售价曝光:好看还便宜
- mysql哨兵机制_Sentinel:万字详解微服务的哨兵机制,我跪了
- java 中的LongAdder
- GIT入门笔记(2)- 典型的工作模式
- 数据分析数据可视化(二)
- varnish02 代理多台后端服务器
- python借助selenium实现雪球网的登录
- 我如何构建Pomodoro Clock应用程序,以及在此过程中学到的课程
- C#高级编程——C#扩展方法+接口,定义统一的搜索接口,基于Unity(三)——图文详解加源码
- 【SpringBoot】十八、拦截器 interceptor
- python驾到~障碍通通闪开,美女批量入内存~
- 公众号滑动图代码_【公众号运营】文章图片滑动效果实现方法
- matlab中clock是什么,matlab中的clock
- 程序员七夕特刊,绝无狗粮添加剂
热门文章
- 更改html默认浏览器,如何设置或默认浏览器更改为浏览器,火狐,IE
- 【题解】CF1418C Mortal Kombat Tower
- 用计算机刻录光盘,图文详解怎么用电脑刻录光盘
- Hive执行报错CannotObtainBlockLengthException: Cannot obtain block length for LocatedBlock
- 1.(MySQL Router+MGR)MySQL Shell安装与用法
- 删除linkinfo.dll
- excel怎么自动填充连续数字
- 计算机操作系统产生的先后顺序,任务调度优先级
- sre工程师_什么是SRE? 现场可靠性工程师的重要作用
- Meltdown漏洞分析