💻 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