C++如何将YAML映射为std::map容器_YAML::as转换用法【实战】

云宇吖_5290

云宇吖_5290

2026-04-04

734人浏览

原创

YAML::as() 不能直接用于嵌套或类型混杂的 YAML 映射,因其仅特化于扁平同质标量映射,遇 null/list/嵌套 map 会抛 BadConversion 异常;安全做法是先 IsMap() 校验,再迭代键值对并显式处理每种类型。

c++如何将yaml映射为std::map容器_yaml::as转换用法【实战】

YAML::as<:map std::string>> 不能直接用 —— 因为 libyaml-cpp 默认不支持自动映射嵌套结构到 std::map,尤其当 YAML 值类型混杂(如字符串、数字、null)时会抛 BadConversion 异常。

为什么 node.as<:map std::string>>() 大概率失败

libyaml-cpp 的 as 模板机制只对“扁平同质映射”有默认特化,且要求 YAML 中所有 value 都是 scalar(即字符串、数字、bool),一旦出现 null、list 或嵌套 map,就会在运行时触发 YAML::BadConversion。更关键的是:它根本不识别 std::map 的 key 类型是否匹配 —— 即使你写成 std::map<:string int>,只要某个 value 是字符串,照样崩。

  • node.IsMap() 必须先校验,否则调用 as 前就可能段错误
  • node["key"] 返回的子节点仍需单独判断类型,不能假设都是 scalar
  • 没有自动类型推导:YAML 中的 42 是 int,但 as<:string>() 会失败,得用 as().to_string() 或先转 Scalar

安全读取 YAML 到 std::map<:string std::string> 的实操方式

核心思路:放弃直接 as,改用迭代 + 显式类型转换。把每个 value 转成 string,不管它原本是 int、float 还是 null —— 这才是配置文件解析的真实需求。

std::map<:string std::string> yaml_to_string_map(const YAML::Node& node) {
    std::map<:string std::string> result;
    if (!node.IsMap()) return result;

    for (auto it = node.begin(); it != node.end(); ++it) {
        std::string key = it->first.as<:string>();
        std::string val;
        if (it->second.IsNull()) {
            val = "";
        } else if (it->second.IsScalar()) {
            val = it->second.as<:string>();
        } else {
            // 非标量(list/map)转 JSON 风格字符串,或按需跳过
            val = it->second.ToString(); // ToString() 是安全 fallback
        }
        result[key] = val;
    }
    return result;
}
</:string></:string></:string></:string>
  • 必须用 it->first.as<:string>() 提取 key,YAML key 只能是 scalar
  • it->second.IsNull() 要显式判断,否则 as<:string>() 对 null 抛异常
  • it->second.ToString() 比 as<:string>() 更鲁棒,它内部做了类型适配,但输出格式不可控(如 map 会带缩进)

遇到嵌套结构时,别硬塞进 std::map<:string std::string>

如果 YAML 里有 database: 下挂 host: localhost 和 ports: [5432, 5433],强行 flatten 成 string 会导致信息丢失。这时候该用分层结构:

C++14
C++14

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

下载
  • 用 std::map<:string yaml::node> 保留原始节点引用,延迟解析(推荐)
  • 自定义结构体 + operator>> 重载,配合 node["field"].as() 分字段处理
  • 若必须 string 化嵌套,用 YAML::Emitter 手动序列化子树:YAML::Emitter emitter; emitter second;,再取 emitter.c_str()

编译与链接容易漏掉的点

libyaml-cpp 默认不开启 RTTI,而 as() 依赖 dynamic_cast —— 如果你链接的是 libyaml-cpp.a 且构建时禁用了 RTTI(常见于嵌入式或某些 CMake preset),as 会静默失败或 crash。

  • 检查是否用了 -fno-rtti:在 CMakeLists.txt 中确认 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -frtti")
  • 链接顺序要对:target_link_libraries(myapp yaml-cpp) 必须在可执行目标定义之后
  • 头文件包含路径:确保 #include 而不是裸 ,后者是 libyaml C API

真正麻烦的从来不是怎么把 YAML 读成 map,而是当某天运维往配置里加了个 timeout_ms: null,而你的代码还傻乎乎地 as() —— 这时候没做 IsNull() 判断的那行,就是线上 panic 的起点。

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

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

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

下载

相关标签:

c++

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

相关专题

更多
string转int
string转int

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

2023.08.02

7519

3

css中float用法
css中float用法

css中float属性允许元素脱离文档流并沿其父元素边缘排列,用于创建并排列、对齐文本图像、浮动菜单边栏和重叠元素。想了解更多float的相关内容,可以阅读本专题下面的文章。

2024.04.28

7687

8

C++中int、float和double的区别
C++中int、float和double的区别

本专题整合了c++中int和double的区别,阅读专题下面的文章了解更多详细内容。

2025.10.23

904

4

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

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

2023.09.22

569

3

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

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

2024.03.01

1698

6

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.03

1938

5

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

2023.09.04

3184

5

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

2023.10.24

6384

49

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

2023.11.24

6549

6

热门下载

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

精品课程

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

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

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

共0课时 | 0人学习