Skip to content

yaml-cpp — YAML 解析

yaml-cpp 是 C++ 最流行的 YAML 解析库,API 简洁,支持读写 YAML 配置文件。

安装

bash
vcpkg install yaml-cpp

# CMake
find_package(yaml-cpp REQUIRED)
target_link_libraries(myapp PRIVATE yaml-cpp::yaml-cpp)

读取 YAML

yaml
# config.yaml
server:
  host: localhost
  port: 8080
  workers: 4

database:
  url: postgresql://localhost/mydb
  pool_size: 10
  timeout: 30

features:
  - name: auth
    enabled: true
  - name: cache
    enabled: false
cpp
#include <yaml-cpp/yaml.h>

YAML::Node config = YAML::LoadFile("config.yaml");

// 访问节点
std::string host = config["server"]["host"].as<std::string>();
int port = config["server"]["port"].as<int>();
int workers = config["server"]["workers"].as<int>(4);  // 默认值

// 安全访问
if (config["server"]["ssl"]) {
    bool ssl = config["server"]["ssl"].as<bool>();
}

// 遍历序列
for (const auto& feature : config["features"]) {
    std::string name = feature["name"].as<std::string>();
    bool enabled = feature["enabled"].as<bool>();
    std::cout << name << ": " << (enabled ? "on" : "off") << "\n";
}

// 遍历映射
for (const auto& kv : config["server"]) {
    std::cout << kv.first.as<std::string>() << " = "
              << kv.second.as<std::string>() << "\n";
}

自定义类型

cpp
struct ServerConfig {
    std::string host;
    int port;
    int workers;
};

// 特化 convert
namespace YAML {
template<>
struct convert<ServerConfig> {
    static Node encode(const ServerConfig& c) {
        Node node;
        node["host"] = c.host;
        node["port"] = c.port;
        node["workers"] = c.workers;
        return node;
    }

    static bool decode(const Node& node, ServerConfig& c) {
        if (!node.IsMap()) return false;
        c.host = node["host"].as<std::string>("localhost");
        c.port = node["port"].as<int>(8080);
        c.workers = node["workers"].as<int>(4);
        return true;
    }
};
}

// 使用
ServerConfig cfg = config["server"].as<ServerConfig>();

写入 YAML

cpp
YAML::Emitter out;
out << YAML::BeginMap;
out << YAML::Key << "name" << YAML::Value << "Alice";
out << YAML::Key << "age" << YAML::Value << 30;
out << YAML::Key << "scores" << YAML::Value
    << YAML::BeginSeq << 95 << 87 << 92 << YAML::EndSeq;
out << YAML::EndMap;

std::ofstream fout("output.yaml");
fout << out.c_str();

关键认知

yaml-cpp 适合配置文件读写。对于性能敏感的场景,考虑 rapidyaml(比 yaml-cpp 快 10x+)。自定义类型通过特化 YAML::convert 实现序列化。

系统学习 C++ 生态,深入底层架构