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)的序列化和反序列化相关推荐

  1. c++11:nlohmann::json进阶使用(三)使用basic_json模板类

    nlohmann::json是非常好用的一个json开源解析库.nlohmann/json的源码是基于C++11标准写的,整个源码就是一个文件 nlohmann/json.hpp,引用非常方便. 关于 ...

  2. hutol json null值没了_JSON数据处理框架Jackson精解第一篇-序列化与反序列化核心用法...

    Jackson是Spring Boot默认的JSON数据处理框架,但是其并不依赖于任何的Spring 库.有的小伙伴以为Jackson只能在Spring框架内使用,其实不是的,没有这种限制.它提供了很 ...

  3. 苹果新的编程语言 Swift 语言进阶(二)--基本数据类型

    一  .   常量和变量 Swift语言 对常量和变量的声明进行了明白的区分 Swift语言的常量类型比C 语言的constants类型更加强大,语义更加明白. 常量和变量的差别是常量在设置或初始化后 ...

  4. c++中nlohmann json的使用

    文章目录 一.json.hpp库下载及安装 1.1 开源地址及引入方法 1.2 demo程序测试 二.nlohmann json基本操作 2.1 由basic value创建json 2.2 由jso ...

  5. 石川es6课程---11、json

    石川es6课程---11.json 一.总结 一句话总结: ` 感觉更方便了一点,增加了一些简写 ` key-value 一样时可以简写:console.log({ a,b}}) ` 里面函数可以简写 ...

  6. C++ nlohmann/json 的主要用法

    文章目录 前言 准备工作 引用头文件: 主要用法: 一.声明与构造 1 纯粹声明 2 内容构造 二.解析与序列化 字符串 解析 序列化 文件:// 比如有文件 c:\rankings.json,其内容 ...

  7. Quartz.Net进阶之二:关于触发器的更多信息

    Quartz.Net进阶之二:关于触发器的更多信息 原文:Quartz.Net进阶之二:关于触发器的更多信息 与作业一样,触发器相对容易使用,但是在您可以充分利用Quartz.NET之前,确实需要了解 ...

  8. mysql 进阶(二)

    ##mysql 进阶(二) ###多表联合查询 什么是多表联合查询 前面所讲的查询语句都是针对一个表的,但是在关系型数据库中,表与表之间是有联系的,所以在实际应用中,经常使用多表查询.多表查询就是同时 ...

  9. C++ 之 nlohmann::json 一个不错的json库

    前言 最近在搞一个C++项目,用到了json和类的相互转化.但是c++没有反射,也没有像java一个方便的插件,没法办只能自己搞一个了.网上找了一下,发现nlohmann::json不错.已经运用到实 ...

  10. 【C++】C++库nlohmann / json的使用

    nlohmann / json for Modern C++ 前言 一.nlohmann/json库简述 1. 概述 2. 优点 3. 配置 二.nlohmann/json库的基本操作 1. 读取 / ...

最新文章

  1. 读一个文件的java程序_java 读文件的几种方法(一)
  2. python基础教程教材-Python3零基础教材电子书合集
  3. 2022年美国大学生数学建模竞赛——Problem C:交易策略
  4. 阮一峰react demo代码研究的学习笔记 - demo 3 debug
  5. POLYCOM RMX2000 激活与初始化 信令板卡初始化
  6. 虚拟网关与正规网关的区别
  7. iPhone13最新外观售价曝光:好看还便宜
  8. mysql哨兵机制_Sentinel:万字详解微服务的哨兵机制,我跪了
  9. java 中的LongAdder
  10. GIT入门笔记(2)- 典型的工作模式
  11. 数据分析数据可视化(二)
  12. varnish02 代理多台后端服务器
  13. python借助selenium实现雪球网的登录
  14. 我如何构建Pomodoro Clock应用程序,以及在此过程中学到的课程
  15. C#高级编程——C#扩展方法+接口,定义统一的搜索接口,基于Unity(三)——图文详解加源码
  16. 【SpringBoot】十八、拦截器 interceptor
  17. python驾到~障碍通通闪开,美女批量入内存~
  18. 公众号滑动图代码_【公众号运营】文章图片滑动效果实现方法
  19. matlab中clock是什么,matlab中的clock
  20. 程序员七夕特刊,绝无狗粮添加剂

热门文章

  1. 更改html默认浏览器,如何设置或默认浏览器更改为浏览器,火狐,IE
  2. 【题解】CF1418C Mortal Kombat Tower
  3. 用计算机刻录光盘,图文详解怎么用电脑刻录光盘
  4. Hive执行报错CannotObtainBlockLengthException: Cannot obtain block length for LocatedBlock
  5. 1.(MySQL Router+MGR)MySQL Shell安装与用法
  6. 删除linkinfo.dll
  7. excel怎么自动填充连续数字
  8. 计算机操作系统产生的先后顺序,任务调度优先级
  9. sre工程师_什么是SRE? 现场可靠性工程师的重要作用
  10. Meltdown漏洞分析