yaml-cpp para C++: guia completo com exemplos práticos
1. O que é e para que serve
yaml-cpp é uma biblioteca leve e moderna em C++ para análise e geração de arquivos YAML. YAML (YAML Ain't Markup Language) é um formato de serialização de dados legível por humanos, amplamente usado para arquivos de configuração, descrição de estruturas de dados, pipelines de CI/CD (como GitHub Actions, GitLab CI) e troca de dados entre serviços. Diferente do JSON, o YAML suporta comentários, strings multilinha, âncoras e aliases, tornando-o ideal para configurações.
Por que usar yaml-cpp? Se você está desenvolvendo uma aplicação em C++ que precisa ler arquivos de configuração (como configurações de servidor, parâmetros de modelo de machine learning ou descrição de dependências), o yaml-cpp oferece uma API simples e type-safe. A biblioteca é totalmente compatível com a especificação YAML 1.2, suporta todos os tipos de dados (escalares, sequências, mapeamentos) e permite converter documentos YAML para estruturas C++ e vice-versa com facilidade.
Principais vantagens: dependências mínimas (apenas a biblioteca padrão C++11/14/17), compilação opcional header-only, suporte a Unicode, serialização personalizada para tipos definidos pelo usuário e uma comunidade ativa (mais de 5 mil estrelas no GitHub).
2. Instalação
O yaml-cpp não é instalado via gerenciadores de pacotes de linguagens como pip ou npm. Para C++, utilize gerenciadores de pacotes do sistema ou compile a partir do código-fonte.
Linux (Debian/Ubuntu)
sudo apt-get install libyaml-cpp-dev
macOS (Homebrew)
brew install yaml-cpp
Windows (vcpkg)
vcpkg install yaml-cpp
Compilação a partir do código-fonte (CMake)
git clone https://github.com/jbeder/yaml-cpp.git
cd yaml-cpp
mkdir build && cd build
cmake -DYAML_BUILD_SHARED_LIBS=ON ..
make
sudo make install
Após a instalação, inclua a biblioteca no seu CMakeLists.txt:
find_package(yaml-cpp REQUIRED)
target_link_libraries(meu_projeto yaml-cpp)
3. Início rápido — exemplo mínimo funcional
Crie um arquivo config.yaml:
servidor:
host: "localhost"
porta: 8080
debug: true
Vamos lê-lo com yaml-cpp:
#include <iostream>
#include <yaml-cpp/yaml.h>
int main() {
// Carrega o arquivo YAML
YAML::Node config = YAML::LoadFile("config.yaml");
// Lê os valores
std::string host = config["servidor"]["host"].as<std::string>();
int porta = config["servidor"]["porta"].as<int>();
bool debug = config["debug"].as<bool>();
std::cout << "Host: " << host << "\n";
std::cout << "Porta: " << porta << "\n";
std::cout << "Debug: " << std::boolalpha << debug << "\n";
return 0;
}
Compilação: g++ -std=c++17 main.cpp -lyaml-cpp -o app
4. Principais métodos/funções/classes
4.1. YAML::Node — classe principal para trabalhar com nós
Assinatura: class YAML::Node
Descrição: Representa qualquer elemento de um documento YAML: escalar, sequência (array) ou mapeamento (dicionário). Suporta iteração, acesso por chave/índice e verificação de tipo.
YAML::Node node;
node["nome"] = "Alice";
node["idade"] = 30;
node["hobbies"].push_back("leitura");
node["hobbies"].push_back("programação");
std::cout << node["nome"].as<std::string>() << "\n"; // Alice
std::cout << node["hobbies"][0].as<std::string>() << "\n"; // leitura
4.2. YAML::LoadFile() — carregar de arquivo
Assinatura: YAML::Node YAML::LoadFile(const std::string& arquivo)
Descrição: Carrega e analisa um arquivo YAML do disco. Lança uma exceção YAML::BadFile se o arquivo não existir ou não puder ser aberto, e YAML::ParserException se o conteúdo for inválido.
try {
YAML::Node config = YAML::LoadFile("config.yaml");
// Processa o nó...
} catch (const YAML::Exception& e) {
std::cerr << "Erro ao carregar YAML: " << e.what() << "\n";
}
4.3. YAML::Load() — carregar de string
Assinatura: YAML::Node YAML::Load(const std::string& conteudo)
Descrição: Analisa uma string contendo YAML diretamente. Útil para dados vindos de rede, banco de dados ou entrada do usuário.
std::string dados = "nome: João\nidade: 25";
YAML::Node pessoa = YAML::Load(dados);
std::cout << pessoa["nome"].as<std::string>() << "\n"; // João
4.4. YAML::Emitter — gerar saída YAML
Assinatura: class YAML::Emitter
Descrição: Classe para gerar documentos YAML formatados. Suporta fluxo encadeado, controle de indentação e formatação de estilos (bloco vs. fluxo).
YAML::Emitter emissor;
emissor << YAML::BeginMap;
emissor << YAML::Key << "nome";
emissor << YAML::Value << "Maria";
emissor << YAML::Key << "habilidades";
emissor << YAML::Value << YAML::BeginSeq;
emissor << "Python" << "C++" << "JavaScript";
emissor << YAML::EndSeq;
emissor << YAML::EndMap;
std::cout << emissor.c_str() << "\n";
// Saída:
// nome: Maria
// habilidades: [Python, C++, JavaScript]
4.5. Verificação de tipo e iteração
Métodos: IsScalar(), IsSequence(), IsMap(), IsNull()
Descrição: Permitem verificar o tipo do nó antes de acessar os dados, evitando exceções.
YAML::Node dados = YAML::Load("[1, 2, 3, quatro]");
if (dados.IsSequence()) {
for (size_t i = 0; i < dados.size(); ++i) {
if (dados[i].IsScalar()) {
std::cout << "Item " << i << ": " << dados[i].as<std::string>() << "\n";
}
}
}
4.6. Serialização personalizada
Descrição: Permite que tipos C++ personalizados sejam convertidos para/de YAML, sobrecarregando os operadores >> e <<.
struct Ponto {
double x, y;
};
namespace YAML {
template<>
struct convert<Ponto> {
static Node encode(const Ponto& rhs) {
Node node;
node["x"] = rhs.x;
node["y"] = rhs.y;
return node;
}
static bool decode(const Node& node, Ponto& rhs) {
if(!node.IsMap() || node.size() != 2)
return false;
rhs.x = node["x"].as<double>();
rhs.y = node["y"].as<double>();
return true;
}
};
}
// Uso:
Ponto p = node.as<Ponto>();
5. Conclusão
O yaml-cpp é uma ferramenta essencial para qualquer desenvolvedor C++ que trabalhe com arquivos de configuração ou dados estruturados. Sua API intuitiva, suporte completo ao padrão YAML 1.2 e flexibilidade fazem dela a escolha ideal para projetos modernos. Com este guia, você já tem tudo o que precisa para começar a usar yaml-cpp em seus próprios projetos. Explore a documentação oficial e o repositório no GitHub para descobrir recursos avançados como âncoras, tags personalizadas e muito mais.
Também na biblioteca
candle para Rust: guia completo com exemplos práticos
Aprendizado de Máquina em C++: Visão Geral das Principais Bibliotecas
Gorilla Mux para Go: guia completo com exemplos
Joi para JavaScript (Node.js): guia completo com exemplos