std::expected
Use case
Error handling without exceptions
Explanation
std::expected<T, E> holds either a value or an error. Like Rust’s Result<T, E>. Better than std::optional when you need error info.
Code
#include <cstdint>
#include <cstring>
#include <expected>
#include <print>
#include <utility>
enum class ParseError {
InvalidMagic,
TooShort,
};
std::expected<uint32_t, ParseError> parseMagic(const uint8_t *data,
size_t size) {
if (size < 4) {
return std::unexpected(ParseError::TooShort);
}
uint32_t magic;
std::memcpy(&magic, data, sizeof(magic));
// https://en.wikipedia.org/wiki/Mach-O
if (magic != 0xFEEDFACF && magic != 0xFEEDFACE) {
return std::unexpected(ParseError::InvalidMagic);
}
return magic;
}
int main() {
std::array<uint8_t, 4> buffer = {0xCF, 0xFA, 0xED, 0xFE};
auto result = parseMagic(buffer.data(), buffer.size());
if (result) {
std::println("Magic: {:#x}", result.value());
} else {
std::println("Error: {}", std::to_underlying(result.error()));
}
return 0;
}
Output
$ ./src/c++23/build/std-expected
Magic: 0xfeedfacf