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. 计算机网络技术专业毕业大作业答案,计算机网络技术大作业考核要求A卷
  2. gdb调试问题Missing separate debuginfos, use: debuginfo-install
  3. 50种优化数据库的方法
  4. spring mvc 返回html 乱码,解决springmvc使用ResponseBody注解返回json中文乱码问题
  5. PHP base64数据与图片的互相转换
  6. 求4个数字组成的不重复三位数,Python简洁解法
  7. xshell无法显示汉字
  8. 华为linux用什么浏览器,Linux系统浏览器最受用户欢迎前十排名
  9. AM3352 uboot中对NandFlash坏块的处理
  10. java poi Excel加密文件导出和下载
  11. js控制wmplayer
  12. 解决问题:cv::Exception,位于内存位置 0x000000D2956FE120 处
  13. Linux系统卸载virtualbox,如何在Mac上卸载VirtualBox
  14. android系统开发 AP 和 BP 简要说明
  15. matlab 模拟 峰信号
  16. signature=f380c172efecdd0f7b9329d16d09ca45,Virtual Identity Signs in Online Communication
  17. 用网线实现两台电脑之间的大文件传输(使用电脑备份)
  18. EL表达式写三目运算
  19. CSU1020-真三国无双-模拟
  20. LeetCode每日一题——Day1

热门文章

  1. 我对硬盘MBR、DBR、BPB、FAT和FDT的理解
  2. 苹果电子邮件怎么注册_无需购买 iPhone,可以使用哪些苹果的优质服务?
  3. html加载三维地图,Cesium加载三维地形及WMS地图,并实现动态控制显示
  4. MongoDB ODM
  5. 物理化学第6版笔记和课后答案(天津大学)
  6. 给Date加上23时59分59秒
  7. 【IoT】创业:产品生产之老化测试
  8. 在就业创业中,您觉得最重要的是什么?
  9. 衣带渐宽终不悔,为伊消得人憔悴--DbHelper增强版
  10. Python爬虫入门教程 7-100 蜂鸟网图片爬取之二