Inconsistent behavior with std::variant and std::visit when handling exceptions in C++20
I'm collaborating on a project where I encountered an unexpected scenario when using `std::variant` in conjunction with `std::visit` to handle different types of exceptions in my C++20 application... The goal is to catch specific exceptions and perform different actions based on the type of exception caught. However, I'm experiencing inconsistent behavior that seems to depend on the order of the types defined in the `std::variant`. Hereโs a simplified version of my code: ```cpp #include <iostream> #include <variant> #include <stdexcept> struct ExceptionA : std::exception { const char* what() const noexcept override { return "Exception A occurred"; } }; struct ExceptionB : std::exception { const char* what() const noexcept override { return "Exception B occurred"; } }; using MyVariant = std::variant<ExceptionA, ExceptionB>; void handle_exception(const MyVariant& e) { std::visit([](const auto& ex) { std::cout << ex.what() << '\n'; }, e); } void risky_function() { throw ExceptionB(); // Change this to ExceptionA() to test the other case } int main() { try { risky_function(); } catch (const std::exception& e) { MyVariant ev = std::holds_alternative<ExceptionA>(e) ? ExceptionA() : ExceptionB(); handle_exception(ev); } } ``` Running this code, I expect to see "Exception B occurred" when `risky_function` throws `ExceptionB`. However, if I change the order of the types in `MyVariant` or if I throw `ExceptionA`, I sometimes get a runtime behavior indicating that the variant is in an unexpected state, specifically an `std::bad_variant_access`. After debugging, I noticed that `std::holds_alternative` does not correctly match the thrown exception type with the variant. Iโve verified that `std::variant` is properly initialized, and the exception handling logic seems sound. Iโve also checked that the types in the variant are indeed derived from `std::exception` as expected. Is there a specific way to properly handle exceptions using `std::variant` and `std::visit` without running into these runtime errors? Are there best practices for matching types within a `std::variant` that I might be missing? This scenario is causing confusion that Iโve spent quite a bit of time trying to resolve. Thanks in advance for any insights! This is my first time working with C++ latest. Thanks, I really appreciate it! What would be the recommended way to handle this?