c++如何将Json数据解析为std::variant动态类型列表【进阶】

轻雪酱_7340

轻雪酱_7340

2026-04-08

854人浏览

原创

不能。std::variant是编译期确定类型的闭合集合,而json值类型在运行时才可知,需显式列出所有映射类型(如std::nullptr_t、bool、int64_t、double、std::string、std::vector、std::map),否则解析失败或访问异常。

c++如何将json数据解析为std::variant动态类型列表【进阶】

std::variant 能否直接承载任意 JSON 值?

不能。标准 std::variant 是编译期确定类型的闭合集合,而 JSON 值(如 null、number、string、array、object、boolean)在运行时才可知。你必须显式列出所有可能的 C++ 类型,并确保它们能一一映射 JSON 的六种基本类型。

常见错误是只写 std::variant<int std::string bool></int>,却漏掉 std::nullptr_t(对应 null)、double(JSON number 可能是浮点)、std::vector<t></t>(array)、std::map<:string t></:string>(object)——这会导致解析到未知类型时抛出 std::bad_variant_access 或静默截断。

推荐基础 variant 定义:

using json_value = std::variant,
    std::map<:string json_value>
>;
</:string>

用 nlohmann/json 解析到 std::variant 列表要绕过哪些坑?

nlohmann/json 默认不支持直接解析进自定义 std::variant,必须手动注册转换逻辑。否则调用 json::get<json_value>()</json_value> 会编译失败或触发未定义行为。

关键操作是特化 nlohmann::adl_serializer 模板,并按 JSON 类型逐一分支处理:

  • 对 json.is_null() → 返回 json_value{nullptr}
  • 对 json.is_boolean() → 返回 json_value{json.get<bool>()}</bool>
  • 对 json.is_number_integer() → 优先转 int64_t(避免 int 溢出),再 fallback 到 double(若值超出 int64 范围)
  • 对 json.is_string() → 返回 std::string 移动构造体
  • 对 json.is_array() → 递归调用 json_value_from_json(elem) 构建 std::vector<json_value></json_value>
  • 对 json.is_object() → 遍历 key-value,value 递归转换,插入 std::map<:string json_value></:string>

注意:nlohmann 的 json::is_number() 不区分整/浮,必须用 is_number_integer() 和 is_number_float() 组合判断,否则整数 123 可能被误读为 double 导致精度丢失或 variant 访问失败。

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载

如何安全访问 variant 列表中的嵌套值?

直接写 std::get<:string>(val)</:string> 很危险——一旦实际类型不是 std::string,程序崩溃。必须先用 std::holds_alternative 检查,或用 std::visit 统一处理。

例如遍历一个 std::vector<json_value></json_value> 并打印所有字符串元素:

for (const auto& item : json_list) {
    std::visit([](const auto& v) {
        using T = std::decay_t<decltype>;
        if constexpr (std::is_same_v<t std::string>) {
            std::cout >) {
            // 递归处理子数组
        } else {
            // 忽略或报错
        }
    }, item);
}
</t></decltype>

要点:

  • 避免裸 std::get,除非你 100% 确认类型(比如刚从 holds_alternative 返回 true)
  • 嵌套结构(如 object 中的 array)必须递归 visit,不能假设一层 flat
  • JSON 的 number 类型在 variant 中分 int64_t 和 double,访问前需分别检查,否则 std::get<double></double> 对整数会 throw

性能与内存开销有哪些隐性代价?

每次 JSON array/object 解析都会触发深度递归 + 多次堆分配(std::vector、std::map、std::string),比原生 nlohmann::json 对象慢 2–5 倍,内存占用高 30–100%。

如果你只需要读取部分字段,别全量解析进 variant 列表——改用 json.at("key").get<int>()</int> 直接提取;如果要做高频查询,考虑用 std::unordered_map 替代 std::map 存 object,但需自行保证 key 字符串生命周期(避免临时 string 被析构)。

最易被忽略的一点:variant 的拷贝成本很高。含 vector/map 的分支拷贝会触发深拷贝,传参务必用 const json_value&,避免无谓复制。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关文章

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

c++

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

2023.08.07

2115

5

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.23

3222

1

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

2023.10.13

1096

3

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

2025.09.10

3679

7

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.02

6299

3

java中boolean的用法
java中boolean的用法

在Java中,boolean是一种基本数据类型,它只有两个可能的值:true和false。boolean类型经常用于条件测试,比如进行比较或者检查某个条件是否满足。想了解更多java中boolean的相关内容,可以阅读本专题下面的文章。

2023.11.13

2130

6

java boolean类型
java boolean类型

本专题整合了java中boolean类型相关教程,阅读专题下面的文章了解更多详细内容。

2025.11.30

143

8

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

2023.09.22

549

3

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

2024.03.01

1678

6

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习