Monadic operations for std::optional
Use case
Chain operations that might fail.
Explanation
transform = apply functions, wrap result in optional (if empty, stays empty). and_then = apply function that returns optional, flatten result (avoids optional<optional<T>>). or_else = provide fallback if empty. No more nested if (opt.has_value()) checks.
Code
#include <cstdint>
#include <optional>
#include <print>
#include <string>
std::optional<uint64_t> findSymbol(const std::string &name) {
if (name == "_main")
return 0x10001000;
return std::nullopt;
}
std::optional<std::string> demangleName(uint64_t addr) {
if (addr == 0x10001000)
return "main";
return std::nullopt;
}
int main() {
auto result =
findSymbol("_main")
.transform([](uint64_t addr) { return addr + 0x10; })
.and_then([](uint64_t addr) { return demangleName(addr - 0x10); })
.or_else([]() -> std::optional<std::string> { return "unknown"; });
std::println("Result: {}", *result);
return 0;
}
Output
$ ./src/c++23/build/monadic-operations
Result: main