yaml-cpp没有yaml::decode函数,仅提供yaml::load/loadfile返回yaml::node;反序列化需特化yaml::convert,并校验字段存在性与类型,推荐用as()而非带默认值版本。

YAML::decode 不存在,别被名字骗了
YAML-CPP 没有 YAML::decode 这个函数,这是常见误解。官方 API 只提供 YAML::Load(从字符串/文件读取)和 YAML::LoadFile,返回 YAML::Node;后续解析靠重载 operator>> 或手动遍历节点。所谓“decode”其实是用户自己实现的反序列化逻辑。
给自定义类加 YAML::convert 特化是核心步骤
必须在全局命名空间(或 YAML 命名空间内)为你的类特化 YAML::convert<yourclass></yourclass>,否则 YAML::Node 转换会编译失败。这个特化要同时支持 encode(序列化)和 decode(反序列化),哪怕你只用后者。
- 特化结构体必须继承
YAML::convert<yourclass></yourclass>,不能只写函数 -
decode函数里必须检查字段是否存在、类型是否匹配,否则运行时访问node["field"]可能抛YAML::TypedBadConversion - 推荐用
node["field"].as<int>()</int>而非node["field"].as<int>(&default_value)</int>,后者在字段缺失时不触发异常,容易掩盖配置错误
namespace YAML {
template
struct convert<person> {
static Node encode(const Person& rhs) {
Node node;
node["name"] = rhs.name;
node["age"] = rhs.age;
return node;
}
static bool decode(const Node& node, Person& rhs) {
if (!node.IsMap()) return false;
if (!node["name"] || !node["name"].IsScalar()) return false;
if (!node["age"] || !node["age"].IsScalar()) return false;
rhs.name = node["name"].as<:string>();
rhs.age = node["age"].as<int>();
return true;
}
};
}</int></:string></person>
反序列化时别直接用 operator>>,先校验再转换
很多教程直接写 node >> obj,但这个操作符依赖上面的 convert 特化,且不返回错误信息。一旦字段类型错(比如把字符串当整数读),会抛 YAML::TypedBadConversion,而没做 try/catch 就 crash。
- 建议封装一层安全转换函数,捕获异常并返回
std::optional<t></t>或bool+ 输出错误位置 - 对嵌套对象,确保其成员类也完成了
YAML::convert特化,否则node["child"].as<child>()</child>编译不过 - 数组映射到
std::vector时,node.size()和node.IsSequence()必须先检查,空数组或非 sequence 类型会导致as<vector>>()</vector>抛异常
中文键名、注释、锚点这些 YAML 特性会影响解析吗?
YAML-CPP 默认支持 UTF-8 编码的中文键名(只要源文件保存为 UTF-8,且编译器支持),但要注意:Windows 下 MSVC 默认 ANSI 编码,可能需加 #pragma execution_character_set("utf-8");GCC/Clang 一般没问题。
- 注释会被完全忽略,无法通过 API 读取 —— 别指望用注释传元数据
- 锚点(
&ref)和引用(*ref)在YAML::Node中已自动解引用,你看到的是展开后的值,不是原始语法结构 - 如果 YAML 文件含制表符缩进,YAML-CPP 会报
YAML::ParserException:YAML 规范禁止 tab 缩进,必须用空格
真正容易被忽略的是:YAML-CPP 的 Node 是引用语义,多次调用 as<t>()</t> 不会重复解析,但修改 Node 内容(如 node["x"] = 42)会影响所有持有该节点的变量 —— 这点和 JSON 库差异很大,调试时容易误判数据来源。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











