În dezvoltarea de software de înaltă performanță (motoare de jocuri, sisteme embedded, microservicii HFT), utilizarea excepțiilor clasice (throw / catch) este adesea descurajată sau complet dezactivată (-fno-exceptions) din cauza costului de performanță la derularea stivei (stack unwinding). Introdus în C++23, tipul de date std::expected<T, E> oferă o alternativă funcțională elegantă: o funcție returnează fie o valoare așteptată de tipul T, fie o eroare detaliată de tipul E (ambele stocate pe stivă fără nicio alocare dinamică).
Tratarea funcțională a erorilor cu std::expected
#include <expected>
#include <string>
#include <print>
enum class EroareFisier {
Negasit,
AccesInterzis,
FormatInvalid
};
// Funcție care returnează fie conținutul fișierului (string), fie un cod de eroare:
std::expected<std::string, EroareFisier> citesteConfig(const std::string& cale) {
if (cale.empty()) {
return std::unexpected(EroareFisier::Negasit);
}
if (cale == "/etc/shadow") {
return std::unexpected(EroareFisier::AccesInterzis);
}
return "host=127.0.0.1;port=5432;";
}
int main() {
auto rez = citesteConfig("/etc/shadow");
if (rez.has_value()) {
std::println("Configuratie citita: {}", rez.value());
} else {
std::println("Eroare intampinata: codul {}", static_cast<int>(rez.error()));
}
// Înlănțuire monadică modernă (Monadic Operations):
auto lungime = citesteConfig("app.conf")
.transform([](const std::string& s) { return s.length(); })
.value_or(0);
std::println("Lungime configuratie valida: {}", lungime);
return 0;
}