尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

JSON for Modern C++ 中 nlohmann::basic_json::empty() 的深度解析:返回值语义、源码实现与测试验证

JSON for Modern C++ 中 nlohmann::basic_json::empty() 的深度解析:返回值语义、源码实现与测试验证 JSON for Modern C 中 nlohmann::basic_json::empty() 的深度解析返回值语义、源码实现与测试验证【免费下载链接】jsonJSON for Modern C项目地址: https://gitcode.com/GitHub_Trending/js/json本篇指南基于官方 API 文档详解nlohmann::basic_json::empty()接口在 JSON for Modern Cnlohmann/json中的作用与语义它如何判断一个 JSON 值没有元素、对九种值类型分别返回什么并结合 库头文件 中的真实实现与 容量单元测试 验证其正确性。读完后你将掌握该接口的返回值规则、源码级委托机制以及它与size()、迭代器定义之间的等价关系能够在实际工程中安全地用它做容器状态检查。函数签名与语义empty()的完整签名为bool empty() const noexcept;官方定义是检查一个 JSON 值是否没有元素即其size()是否为0。这是一个const成员函数带有 no-throw 保证可以在任何需要只读检查的场景中放心调用包括范围检查、条件分支和断言。从源码位置看该函数位于 include/nlohmann/json.hpp 中capacity容量功能组的开头紧邻size()与max_size()与 C 标准容器的 capacity 接口组布局一致。各值类型的返回值官方文档给出了完整的返回值定义表值类型返回值nulltruebooleanfalsestringfalsenumberfalsebinaryfalseobjectobject_t::empty()的结果arrayarray_t::empty()的结果几个值得注意的点null是唯一天然为空的标量类型。null不持有任何数据因此被视为空。所有其他标量类型布尔、字符串、数字、二进制一律返回false。即使字符串内容长度为 0即json j ;empty()也返回false——因为 JSON 容器本身持有一个 string 值而不是没有元素。官方文档专门用 Notes 一节强调了这一点empty()判断的是JSON 容器本身是否为空而不是容器里存的字符串是否为空。如需判断字符串内容长度应先取回string_t再调用其自身的empty()。object 与 array 才是真正有元素个数的复合类型其返回值委托给底层容器的empty()。对于默认配置array_t std::vectorbasic_json、object_t std::mapstd::string, basic_json这意味着委托给标准库容器的 O(1)empty()。源码实现解析官方文档给出的参考实现非常简单bool empty() const noexcept { return size() 0; }但 include/nlohmann/json.hpp 中的实际实现并没有走size()而是按m_data.m_type直接做类型分派避免了一次间接调用bool empty() const noexcept { switch (m_data.m_type) { case value_t::null: { // null values are empty return true; } case value_t::array: { // delegate call to array_t::empty() return m_data.m_value.array-empty(); } case value_t::object: { // delegate call to object_t::empty() return m_data.m_value.object-empty(); } case value_t::string: case value_t::boolean: case value_t::number_integer: case value_t::number_unsigned: case value_t::number_float: case value_t::binary: case value_t::discarded: default: { // all other types are nonempty return false; } } }可以从中读出三点实现细节basic_json是类型标签 联合数据结构。内部成员m_data.m_type记录当前值属于value_t枚举的哪一种m_data.m_value中则存放对应的实际容器array指针、object指针等。empty()的第一层判断完全由类型标签驱动。委托而非计算。对 array/object函数直接把判断交给array_t/object_t的empty()因此行为与所用容器类型严格一致。若用户通过模板参数改用 ordered_map 作为 object 容器即ordered_json从源码结构看ordered_map继承自std::vectorstd::pairconst Key, T见 include/nlohmann/ordered_map.hpp其empty()同样是 O(1)空对象判断结果与std::map版本完全一致。discarded类型归入非空分支。解析过程中被丢弃discarded的值与字符串、布尔、数字、二进制一样返回false这与文档表中其余类型返回false的语义在实现上闭合。与之对照同文件中的size()实现采用同一套分派结构null返回0array/object 委托size()其余类型返回1。因此文档中empty()即size() 0的定义在两种实现路径下都成立——实际实现只是省去了size()的中间跳转直接对类型标签分派。完整示例与运行结果官方示例源码见 empty.cpp覆盖 null、布尔、整数、浮点、对象、空对象、数组、空数组、字符串共九种情况#include iostream #include nlohmann/json.hpp using json nlohmann::json; int main() { // create JSON values json j_null; json j_boolean true; json j_number_integer 17; json j_number_float 23.42; json j_object {{one, 1}, {two, 2}}; json j_object_empty(json::value_t::object); json j_array {1, 2, 4, 8, 16}; json j_array_empty(json::value_t::array); json j_string Hello, world; // call empty() std::cout std::boolalpha; std::cout j_null.empty() \n; std::cout j_boolean.empty() \n; std::cout j_number_integer.empty() \n; std::cout j_number_float.empty() \n; std::cout j_object.empty() \n; std::cout j_object_empty.empty() \n; std::cout j_array.empty() \n; std::cout j_array_empty.empty() \n; std::cout j_string.empty() \n; }运行输出与 empty.output 一致true false false false false true false true false逐项对照即可验证上表的语义j_null、j_object_empty、j_array_empty为true布尔、整数、浮点、双元素对象、五元素数组、非空字符串均为false。注意json j_null;的默认构造即 null 值这解释了第一行为true。单元测试对语义的进一步验证tests/src/unit-capacity.cpp 中的TEST_CASE(capacity)对empty()做了系统性验证覆盖 boolean、string、array空/非空、object空/非空、整数、无符号整数、浮点、null 八类场景。除断言各类型的返回真值外例如空数组j.empty() true、非空对象j.empty() false每个场景都额外验证了 C 标准库对空的定义式等价关系CHECK(j.empty() (j.begin() j.end()));即empty()的结果与begin() end()一致。这说明empty()的行为完全符合标准容器语义可以安全地用于是否需要跳过处理这类判断且对const与非常量对象的行为一致测试中对j和j_const均做了断言。异常安全与复杂度异常安全No-throw guarantee该函数从不抛出异常函数签名中的noexcept在 源码 中直接可见。时间复杂度常数量级——前提是array_t与object_t满足 C 标准 Container 概念即其empty()为 O(1)。默认的std::vector与std::map均满足该条件。版本历史与使用建议empty()自version 1.0.0起提供。version 3.8.0起扩展为对 binary 类型返回falsebinary 支持本身即在该版本引入之前的版本不存在这一分支。实践建议判断对象/数组里有没有内容时优先用empty()而不是size() 0或begin() end()语义更清晰且与库的实现路径一致判断字符串值是否为空串时不要用j.empty()应先用j.is_string()确认类型再对取回的string_t判断长度对解析后的null值做判空时empty()返回true若需区分 null 与空容器可配合is_null()、is_array()、is_object()使用。相关接口size()empty()定义的直接依据array_t/object_t决定委托行为与 O(1) 复杂度的底层容器类型ordered_map用于ordered_json的保序对象容器同样支持 O(1) 的empty()委托。【免费下载链接】jsonJSON for Modern C项目地址: https://gitcode.com/GitHub_Trending/js/json创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表