https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90246
--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> --- It's too late to change this now, but we could still improve the messages: --- a/libstdc++-v3/include/std/variant +++ b/libstdc++-v3/include/std/variant @@ -1200,10 +1200,12 @@ namespace __variant { public: bad_variant_access() noexcept : _M_reason("Unknown reason") { } + const char* what() const noexcept override { return _M_reason; } private: + // Must only be called with a string literal bad_variant_access(const char* __reason) : _M_reason(__reason) { } const char* _M_reason; @@ -1211,10 +1213,20 @@ namespace __variant friend void __throw_bad_variant_access(const char* __what); }; + // Must only be called with a string literal inline void __throw_bad_variant_access(const char* __what) { _GLIBCXX_THROW_OR_ABORT(bad_variant_access(__what)); } + inline void + __throw_bad_variant_access(bool __valueless) + { + if (__valueless) [[__unlikely__]] + __throw_bad_variant_access("std::get: variant is valueless"); + else + __throw_bad_variant_access("std::get: wrong index for variant"); + } + template<typename... _Types> class variant : private __detail::__variant::_Variant_base<_Types...>, @@ -1584,7 +1596,7 @@ namespace __variant static_assert(_Np < sizeof...(_Types), "The index should be in [0, number of alternatives)"); if (__v.index() != _Np) - __throw_bad_variant_access("Unexpected index"); + __throw_bad_variant_access(__v.valueless_by_exception()); return __detail::__variant::__get<_Np>(__v); } @@ -1595,7 +1607,7 @@ namespace __variant static_assert(_Np < sizeof...(_Types), "The index should be in [0, number of alternatives)"); if (__v.index() != _Np) - __throw_bad_variant_access("Unexpected index"); + __throw_bad_variant_access(__v.valueless_by_exception()); return __detail::__variant::__get<_Np>(std::move(__v)); } @@ -1606,7 +1618,7 @@ namespace __variant static_assert(_Np < sizeof...(_Types), "The index should be in [0, number of alternatives)"); if (__v.index() != _Np) - __throw_bad_variant_access("Unexpected index"); + __throw_bad_variant_access(__v.valueless_by_exception()); return __detail::__variant::__get<_Np>(__v); } @@ -1617,7 +1629,7 @@ namespace __variant static_assert(_Np < sizeof...(_Types), "The index should be in [0, number of alternatives)"); if (__v.index() != _Np) - __throw_bad_variant_access("Unexpected index"); + __throw_bad_variant_access(__v.valueless_by_exception()); return __detail::__variant::__get<_Np>(std::move(__v)); } @@ -1648,7 +1660,7 @@ namespace __variant visit(_Visitor&& __visitor, _Variants&&... __variants) { if ((__variants.valueless_by_exception() || ...)) - __throw_bad_variant_access("Unexpected index"); + __throw_bad_variant_access("std::visit: variant is valueless"); return __do_visit(std::forward<_Visitor>(__visitor), std::forward<_Variants>(__variants)...); @@ -1660,7 +1672,7 @@ namespace __variant visit(_Visitor&& __visitor, _Variants&&... __variants) { if ((__variants.valueless_by_exception() || ...)) - __throw_bad_variant_access("Unexpected index"); + __throw_bad_variant_access("std::visit<R>: variant is valueless"); if constexpr (std::is_void_v<_Res>) (void) __do_visit<false, false>(std::forward<_Visitor>(__visitor),