How do I use std::expected-like types in C++?

Learn how to implement std::expected-like types in C++, enabling better error handling and optional values with a more expressive interface than traditional methods.

std::expected, C++, error handling, optional values, C++20, programming, software development

        #include <iostream>
        #include <variant>  // For std::variant
        #include <optional> // For std::optional
        #include <string>

        // Define a simple Expected type
        template <typename T, typename E>
        class Expected {
        public:
            Expected(T value) : data_(std::move(value)), has_value_(true) {}
            Expected(E error) : data_(std::move(error)), has_value_(false) {}

            bool has_value() const { return has_value_; }
            T value() && { return std::get<T>(data_); }
            E error() && { return std::get<E>(data_); }

        private:
            std::variant<T, E> data_;
            bool has_value_;
        };

        // Example usage of Expected
        Expected<int, std::string> divide(int a, int b) {
            if (b == 0) {
                return Expected<int, std::string>("Division by zero");
            }
            return Expected<int, std::string>(a / b);
        }

        int main() {
            auto result = divide(10, 2);
            if (result.has_value()) {
                std::cout << "Result: " << result.value() << std::endl;
            } else {
                std::cout << "Error: " << result.error() << std::endl;
            }

            auto errorResult = divide(10, 0);
            if (errorResult.has_value()) {
                std::cout << "Result: " << errorResult.value() << std::endl;
            } else {
                std::cout << "Error: " << errorResult.error() << std::endl;
            }

            return 0;
        }
        

std::expected C++ error handling optional values C++20 programming software development