nlohmann json C++ 解析

学习材料:nlohmann json

json官方

源码解析

源码

要学习并理解这份代码,可以按照以下步骤进行,逐步梳理代码的逻辑:

基本步骤:

  1. 配置宏:

    • 理解用于配置的宏定义,这些宏控制库的不同特性和行为。
    • 例如,#if JSON_DIAGNOSTICS 用于控制诊断特性的启用。
  2. 核心类 basic_json:

    • 分析 basic_json 类,它是整个库的核心,表示一个 JSON 值。
    • 理解类中的成员变量(如 value_t 枚举和 json_value 联合体)和它们的作用。
    • 阅读并理解类的构造函数、析构函数、拷贝和移动构造函数及赋值运算符。
    • 学习类中的成员函数,例如 operator[]getsetis 等。
  3. 序列化和反序列化:

    • 理解用于将 JSON 值转换为字符串和从字符串转换回 JSON 值的序列化和反序列化逻辑。
    • 例如,json_serializer 类中的 serializedeserialize 方法。
  4. 异常处理:

    • 了解用于处理错误的自定义异常类,例如 json_exception
    • 理解这些异常类如何与标准的异常处理机制集成,并提供有用的错误信息。

basic_json

The basic_json class is the core of the library, encapsulating all JSON types. Its design includes:

Type Management: An internal enum to manage the type of the JSON value.
Storage: A union to store different types efficiently.
Constructors and Destructors: To handle different JSON types.
Operators: Overloaded operators for ease of use.

// basic_json 类用于表示一个 JSON 值
template<typename BasicJsonType>
class basic_json
{
private:json_value m_value; // 存储 JSON 值的联合体value_t m_type = value_t::null; // 当前 JSON 值的类型public:// 构造函数basic_json() noexcept;basic_json(value_t t) noexcept;// 析构函数~basic_json() noexcept;// 拷贝和移动构造函数及赋值运算符basic_json(const basic_json& other);basic_json(basic_json&& other) noexcept;basic_json& operator=(const basic_json& other);basic_json& operator=(basic_json&& other) noexcept;// 成员函数// 示例:重载运算符 []reference operator[](size_type idx){// 检查类型并返回数组元素if (JSON_UNLIKELY(!is_array())){throw type_error::create(305, "cannot use operator[] with " + std::string(type_name()));}return m_value.array->operator[](idx);}
};

类型管理

JSON typevalue_t typeused type
objectobjectpointer to @ref object_t
arrayarraypointer to @ref array_t
stringstringpointer to @ref string_t
booleanboolean@ref boolean_t
numbernumber_integer@ref number_integer_t
numbernumber_unsigned@ref number_unsigned_t
numbernumber_float@ref number_float_t
binarybinarypointer to @ref binary_t
nullnullno value is stored

定义一个枚举来表示 JSON 值的类型

enum class value_t : std::uint8_t
{null,             ///< null valueobject,           ///< object (unordered set of name/value pairs)array,            ///< array (ordered collection of values)string,           ///< string valueboolean,          ///< boolean valuenumber_integer,   ///< number value (signed integer)number_unsigned,  ///< number value (unsigned integer)number_float,     ///< number value (floating-point)binary,           ///< binary array (ordered collection of bytes)discarded         ///< discarded by the parser callback function
};

C++11枚举类——enum class

联合体用于高效存储不同类型的 JSON 值

    using string_t = StringType;using boolean_t = BooleanType;using number_integer_t = NumberIntegerType;using number_unsigned_t = NumberUnsignedType;using number_float_t = NumberFloatType;using binary_t = nlohmann::byte_container_with_subtype<BinaryType>;using object_comparator_t = detail::actual_object_comparator_t<basic_json>;union json_value
{std::nullptr_t null;object_t* object;array_t* array;string_t* string;boolean_t boolean;number_integer_t number_integer;number_unsigned_t number_unsigned;number_float_t number_float;binary_t* binary;//构造函数json_value() = default;json_value(boolean_t v) noexcept : boolean(v) {}json_value(number_integer_t v) noexcept : number_integer(v) {}json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}json_value(number_float_t v) noexcept : number_float(v) {}json_value(value_t t){switch (t){case value_t::object:{object = create<object_t>();break;}case value_t::array:{array = create<array_t>();break;}case value_t::string:{string = create<string_t>("");break;}
.......}// 联合体的构造函数json_value() noexcept : null(nullptr) {}
};
Explanation of the Code

The code snippet you provided is a part of the nlohmann/json library’s template declarations and type definitions. Let’s break it down step-by-step.

1. number_integer_t
using number_integer_t = NumberIntegerType;

This line is a type alias declaration in C++. It creates an alias number_integer_t for NumberIntegerType. Essentially, wherever number_integer_t is used, it refers to NumberIntegerType.

2. Template Declaration Macro
#define NLOHMANN_BASIC_JSON_TPL_DECLARATION                                \template<template<typename, typename, typename...> class ObjectType,   \template<typename, typename...> class ArrayType,              \class StringType, class BooleanType, class NumberIntegerType, \class NumberUnsignedType, class NumberFloatType,              \template<typename> class AllocatorType,                       \template<typename, typename = void> class JSONSerializer,     \class BinaryType,                                             \class CustomBaseClass>

This macro defines a template declaration for the basic_json class template. It simplifies the repeated use of this long template parameter list by allowing the declaration to be inserted with a macro.

3. NumberIntegerType Definition
class NumberIntegerType = std::int64_t;

This line defines NumberIntegerType as a class that is actually an alias for std::int64_t. This indicates that the default type for representing integer numbers in JSON is std::int64_t, a 64-bit signed integer.

Reasons for This Design
a. Template Flexibility

The use of template parameters for various types (like NumberIntegerType) allows the basic_json class to be highly flexible. Users of the library can customize the JSON value types according to their needs. For instance, they can choose different types for integers, floats, strings, etc., based on specific requirements like memory constraints or performance needs.

b. Type Aliases for Readability

The using alias (using number_integer_t = NumberIntegerType) improves code readability and maintainability. It allows the library to use meaningful names throughout the implementation, making it clear what type each alias represents.

c. Macros for Simplification

The macro NLOHMANN_BASIC_JSON_TPL_DECLARATION is used to simplify the repeated declaration of the template parameter list. This avoids redundancy and potential errors from copying the long template parameter list multiple times in the code.

Example Usage

Here’s a simplified example of how these templates and type aliases might be used in the basic_json class:

NLOHMANN_BASIC_JSON_TPL_DECLARATION
class basic_json
{
public:using integer_t = NumberIntegerType; // Using the template parameter typeusing unsigned_t = NumberUnsignedType;using float_t = NumberFloatType;// Example function using the type aliasesvoid set_number(integer_t value){m_value.number_integer = value;m_type = value_t::number_integer;}private:union json_value{integer_t number_integer;unsigned_t number_unsigned;float_t number_float;// Other types...} m_value;value_t m_type = value_t::null;
};

In this example:

  • The basic_json class template is declared using the macro NLOHMANN_BASIC_JSON_TPL_DECLARATION.
  • The type aliases integer_t, unsigned_t, and float_t are used within the class to refer to the respective types specified by the template parameters.
  • A member function set_number demonstrates how the type alias integer_t is used to define function parameters and manipulate the union member number_integer.
Summary

This design approach provides flexibility, readability, and maintainability. It allows the basic_json class to be easily customized for different types while keeping the code clean and understandable. The use of type aliases and macros ensures that the code remains concise and reduces the risk of errors from repetitive code.

成员变量

private:// Member variablesjson_value m_value; // Stores the actual datavalue_t m_type; // Represents the type of the stored data

构造函数

https://json.nlohmann.me/api/basic_json/basic_json/
一共有9个构造函数

json_serializer

// json_serializer 类用于 JSON 值的序列化和反序列化
template<typename BasicJsonType>
class json_serializer
{
public:static void serialize(const BasicJsonType& j, string_t& s){// 序列化实现}static void deserialize(const string_t& s, BasicJsonType& j){// 反序列化实现}
};// json_exception 类用于处理 JSON 库中的异常
class json_exception : public std::exception
{
public:explicit json_exception(const std::string& msg) : m_msg(msg) {}const char* what() const noexcept override{return m_msg.c_str();}private:std::string m_msg;
};

代码

未完待续

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/17848.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java-常见面试题收集(十五)

二十四 Elasticsearch 1 Elasticsearch 的倒排索引 传统的检索方式是通过文章&#xff0c;逐个遍历找到对应关键词的位置。 倒排索引&#xff0c;是通过分词策略&#xff0c;形成了词和文章的映射关系表&#xff0c;也称倒排表&#xff0c;这种词典 映射表即为倒排索引。 其中…

印度政策变革下,中国跨国企业如何应对?一家高科技企业的数据本地化之路

自2001年底印度加入世贸组织以来&#xff0c;印度政府一直积极采取措施促进经济的发展&#xff0c;推出相关政策吸引外资并调整产业结构&#xff0c;以推动经济实现跨越式增长。外资纷纷涌入印度&#xff0c;在各地建立大规模的企业&#xff0c;促使印度成为全球工厂之一&#…

回答网友问题:在C# 中调用非托管DLL

在一个QQ群里&#xff0c;有人在问如何“在C# 中调用非托管DLL”。 俺脑子抽抽了一下&#xff0c;就回了一句“你喜欢用那种声明方式&#xff0c;就用那种方式去调用。” 然后就有人说&#xff1a;“参数声明要和DLL的声明完全一致”。 俺脑子又抽抽了一下&#xff0c;又回了…

图论中的两种递推计数法

递推计数法 生成树计数&#xff1a; τ ( G ) τ ( G − e ) τ ( G ⋅ e ) \tau(G) \tau(G-e)\tau(G\cdot e) τ(G)τ(G−e)τ(G⋅e) G的生成树的颗数&#xff0c;可以分为两类&#xff1a;包含边e的为 τ ( G ⋅ e ) \tau(G\cdot e) τ(G⋅e)&#xff0c;不包含边e的为 …

kafka跨地区跨集群同步工具MirrorMaker2 —— 筑梦之路

MM2简介 KIP-382: MirrorMaker 2.0 - Apache Kafka - Apache Software Foundation 有四种运行MM2的方法&#xff1a; As a dedicated MirrorMaker cluster.&#xff08;作为专用的MirrorMaker群集&#xff09; As a Connector in a distributed Connect cluster.&#xff08…

每日一练 - 揭秘高级ACL的奥秘

01 真题题目 以下关于高级 ACL 描述正确的是&#xff1a; A.高级 ACL 支持基于协议类型过滤报文 B.可以过滤的协议号的取值可以是 1-255 C.编号范围 3000-3999 D.可以定义生效时间 E.可以根据 MAC 地址过滤报文 02 真题答案 ABCD 03 答案解析 A. 正确&#xff1a;高级ACL的…

使用IDEA远程debug调试

文章目录 应用背景开启方式IDEA设置启动脚本改造 参考资料 应用背景 springboot项目&#xff0c;部署到服务器上&#xff0c;需要开启远程debug跟踪代码。 使用idea开启远程debug。 开启方式 IDEA设置 选择 Edit Configuration 如图&#xff0c;点击加号&#xff0c;选择Re…

【机器学习】利用机器学习优化陆军战术决策与战场态势感知

&#x1f512;文章目录&#xff1a; &#x1f4a5;1.引言 &#x1f6f4;2.机器学习在陆军战术决策中的应用 &#x1f6e3;️2.1数据收集与预处理 &#x1f304;2.2模型构建与训练&#xff1a; &#x1f305;2.3实时决策支持&#xff1a; &#x1f305;2.4代码实现 &…

力扣:454. 四数相加 II

454. 四数相加 II 给你四个整数数组 nums1、nums2、nums3 和 nums4 &#xff0c;数组长度都是 n &#xff0c;请你计算有多少个元组 (i, j, k, l) 能满足&#xff1a; 0 < i, j, k, l < nnums1[i] nums2[j] nums3[k] nums4[l] 0 示例 1&#xff1a; 输入&#xff…

排序算法——上

一、冒泡排序&#xff1a; 1、冒泡排序算法的思想 我们从左边开始把相邻的两个数两两做比较&#xff0c;当一个元素大于右侧与它相邻的元素时&#xff0c;交换它们之间位置&#xff1b;反之&#xff0c;它们之间的位置不发生变化。冒泡排序是一种稳定的排序算法。 2、代码实现…

5月20日分割等和子集+最后一块石头的重量Ⅱ

416.分割等和子集 给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集&#xff0c;使得两个子集的元素和相等。 示例 1&#xff1a; 输入&#xff1a;nums [1,5,11,5] 输出&#xff1a;true 解释&#xff1a;数组可以分割成 [1, 5, 5] 和…

【ai】LiveKit Agent 的example及python本地开发模式工程实例

title: ‘LiveKit Agent Playground’ playgroundLiveKit Community playground的环境变量&#xff1a;LiveKit API # LiveKit API Configuration LIVEKIT_API_KEYYOUR_API_KEY LIVEKIT_API_SECRETYOUR_API_SECRET# Public configuration NEXT_PUBLIC_LIVEKIT_URLwss://YOUR_…

持续总结中!2024年面试必问 20 道 Rocket MQ面试题(一)

一、请简述什么是RocketMQ&#xff1f; RocketMQ是一个开源的消息中间件&#xff0c;由阿里巴巴团队开发&#xff0c;主要设计用于分布式系统中的异步通信、应用解耦、流量削峰和消息持久化。它支持高吞吐量、高可用性、可扩展性和容错性&#xff0c;是构建大规模实时消息处理…

Linux系统keepalived实现主备高可用方案

Linux系统keepalived实现主备高可用方案 环境准备 装备两台机器&#xff0c;IP地址信息如下&#xff1a; host1&#xff1a; 192.168.18.180 host2&#xff1a; 192.168.18.183 虚拟vip: 192.168.18.188为了测试&#xff0c;分别在两台机器上安装nginx服务&#xff0c;使下面…

React暴露组件的方法给全局作用域调用

在React中&#xff0c;如果你想要暴露组件的方法给全局作用域调用&#xff0c;你可以使用一个全局变量来引用你的组件实例&#xff0c;或者使用Context API来创建一个全局状态&#xff0c;通过它来传递方法引用。 以下是使用Context API的一个简单例子&#xff1a; 创建一个C…

JAVA智慧工厂制造生产管理MES系统,全套源码,多端展示(MES与ERP系统的区别和联系)

MES与ERP系统的区别和联系 MES制造执行系统&#xff0c;是一套面向制造公司车间执行层的生产信息化管理系统。MES 可觉得公司提供涉及制造数据管理、计划排产管理、生产调度管理、库存管理、质量管理、人力资源管理、工作中心、设备管理、工具工装管理、采购管理、成本管理、项…

为什么推荐前端用WebStorm软件编程?

一、介绍 WebStorm是由JetBrains公司开发的一款JavaScript开发工具&#xff0c;被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。它支持JavaScript、ECMAScript 6、TypeScript、CoffeeScript、Dart和Flow等多种语言的代码…

大学搜题软件音乐类?分享三个支持答案和解析的工具 #微信#媒体

高效的学习工具可以帮助我们提高记忆力和理解能力&#xff0c;使知识更加深入人心。 1.彩虹搜题 这是个微信公众号 一款专门供全国大学生使用的查题神器!致力于帮助大学生解决学习上的难题,涵盖了大学生学习所需的学习资料。 下方附上一些测试的试题及答案 1、甲、乙合伙开…

goimghdr,一个有趣的 Python 库!

更多Python学习内容&#xff1a;ipengtao.com 大家好&#xff0c;今天为大家分享一个有趣的 Python 库 - goimghdr。 Github地址&#xff1a;https://github.com/corona10/goimghdr 在图像处理和分析过程中&#xff0c;识别图像文件的类型是一个常见的需求。Python自带的imghdr…

开源与闭源:AI模型发展的两条路径

目录 前言1 数据隐私保护与用户数据安全1.1 开源大模型的透明性与挑战1.2 闭源大模型的控制与责任 2 商业应用的优劣比较2.1 开源大模型的灵活性与创新2.2 闭源大模型的可靠性与服务质量 3 社区参与与合作的差异3.1 开源大模型的社区驱动与协作3.2 闭源大模型的企业主导与保密性…