💻 Exemplos: Capítulo 14: Tratamento de Erros Moderno: noexcept, std::optional e std::variant
💻 Exemplos: Capítulo 14: Tratamento de Erros Moderno: noexcept, std::optional e std::variant
Especialização em Sistemas com C++ • Demonstrações Práticas Compiláveis
🎯 Objetivo dos Exemplos
Apresentar as estratégias modernas de tratamento de erros e modelagem de tipos de dados algébricos em sistemas C++ de alta confiabilidade: a especificação noexcept para otimização de move constructors e chamadas críticas, o uso de std::optional para indicar ausência sem ponteiros nulos, e std::variant com std::visit implementando o padrão de Pattern Matching com o Overload Pattern.
1. Código Fonte Completo (main.cpp)
/**
* @file main.cpp
* @brief Tratamento de erros, noexcept, std::optional e std::variant com std::visit em C++20.
*/
#include <iostream>
#include <string>
#include <optional>
#include <variant>
// 1. O Padrão de Sobrecarga para std::visit (Overload Pattern)
template <class... Ts> struct overloads : Ts... { using Ts::operator()...; };
template <class... Ts> overloads(Ts...) -> overloads<Ts...>;
// Tipos de Retorno do Motor de Transação
struct TransacaoSucesso {
std::string tx_hash;
double valor_processado;
};
struct FalhaRede {
int codigo_socket;
std::string mensagem;
};
struct FalhaSaldoInsuficiente {
double saldo_atual;
double valor_solicitado;
};
// 2. Tipo Algébrico Result (std::variant)
using ResultadoTransacao = std::variant<TransacaoSucesso, FalhaRede, FalhaSaldoInsuficiente>;
// Função Crítica com Especificação noexcept
ResultadoTransacao processar_pagamento(int conta_id, double montante) noexcept {
if (conta_id == 0) {
return FalhaRede{ 504, "Gateway de Pagamento Inacessivel" };
}
if (montante > 10'000.0) {
return FalhaSaldoInsuficiente{ 2'500.0, montante };
}
return TransacaoSucesso{ "0x7F8B9C0012FA", montante };
}
// 3. std::optional para Busca em Dicionário de Hardware
std::optional<std::string> buscar_device_driver(int vendor_id) {
if (vendor_id == 0x10DE) {
return "NVIDIA_RTX_KERNEL_DRIVER_v550";
}
return std::nullopt; // Ausência explícita e segura
}
int main() {
std::cout << "=== CAPÍTULO 14: ERROS MODERNOS, OPTIONAL E VARIANT ===" << '\n';
// Teste com std::optional
std::cout << "\n--- 1. Consulta com std::optional ---" << '\n';
auto driver = buscar_device_driver(0x10DE);
if (driver) {
std::cout << "Driver encontrado: " << *driver << '\n';
}
auto driver_invalido = buscar_device_driver(0xFFFF);
std::cout << "Fallback para driver desconhecido: "
<< driver_invalido.value_or("DRIVER_GENERICO_VESA") << '\n';
// Teste com std::variant e std::visit (Pattern Matching)
std::cout << "\n--- 2. Despacho com std::variant & std::visit ---" << '\n';
ResultadoTransacao resultado = processar_pagamento(1024, 15'000.0);
std::visit(overloads {
[](const TransacaoSucesso& s) {
std::cout << "[SUCESSO] Transacao confirmada: Hash " << s.tx_hash
<< " | Valor: R$ " << s.valor_processado << '\n';
},
[](const FalhaRede& r) {
std::cerr << "[FALHA DE REDE] Erro " << r.codigo_socket << ": " << r.mensagem << '\n';
},
[](const FalhaSaldoInsuficiente& si) {
std::cerr << "[FALHA DE SALDO] Solicitado: R$ " << si.valor_solicitado
<< " | Saldo Disponivel: R$ " << si.saldo_atual << '\n';
}
}, resultado);
return 0;
}
2. Instruções de Compilação e Execução
# Compilação com GCC / Clang
g++ -std=c++20 -Wall -Wextra -O2 main.cpp -o app_variant
./app_variant
# Compilação com MSVC
cl /std:c++20 /EHsc /W4 /O2 main.cpp /Fe:app_variant.exe
.\app_variant.exe
3. Saída Esperada no Terminal
=== CAPÍTULO 14: ERROS MODERNOS, OPTIONAL E VARIANT ===
--- 1. Consulta com std::optional ---
Driver encontrado: NVIDIA_RTX_KERNEL_DRIVER_v550
Fallback para driver desconhecido: DRIVER_GENERICO_VESA
--- 2. Despacho com std::variant & std::visit ---
[FALHA DE SALDO] Solicitado: R$ 15000 | Saldo Disponivel: R$ 2500