Created
February 21, 2026 06:13
-
-
Save dgodfrey206/64edd4246fe4ed01f7711521bce5c0d9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <any> | |
| #include <print> | |
| #include <string> | |
| #include <type_traits> | |
| using namespace std; | |
| #pragma GCC diagnostic ignored "-Wnon-template-friend" | |
| template <class T, class... Ts> | |
| class A : A<Ts...> { | |
| public: | |
| A(T&& t, Ts&&... ts) : | |
| A<Ts...>(std::forward<Ts>(ts)...), | |
| t(std::forward<T>(t)) {} | |
| template <class F> | |
| void visit(F f) { | |
| if constexpr (std::is_invocable_v<F, T>) { | |
| f(t); | |
| } | |
| A<Ts...>::visit(f); | |
| } | |
| T t; | |
| }; | |
| template <class T> | |
| class A<T> { | |
| public: | |
| template <class F> | |
| void visit(F f) { | |
| if constexpr (std::is_invocable_v<F, T>) { | |
| f(t); | |
| } | |
| } | |
| T t; | |
| }; | |
| // Source - https://stackoverflow.com/a/70701479 | |
| // Posted by HolyBlackCat (Modified slightly) | |
| // Retrieved 2026-02-20, License - CC BY-SA 4.0 | |
| namespace detail | |
| { | |
| template<class T> | |
| struct Reader | |
| { | |
| friend auto adl_GetType(Reader<T>); | |
| }; | |
| template<class T, class U> | |
| struct Writer | |
| { | |
| friend auto adl_GetType(Reader<T>){return U{};} | |
| }; | |
| inline void adl_GetType() {} | |
| template<class T> | |
| using Read = std::remove_pointer_t<decltype(adl_GetType(Reader<T>{}))>; | |
| } | |
| class Wrapper { | |
| struct type_tag {}; | |
| template<class...Ts> | |
| static constexpr auto inject_adl_definition() -> decltype(detail::Writer<type_tag, A<Ts...>*>{}, void()) {} | |
| // The conditional is used so that F is a dependent type to prevent instantiation before visit is called | |
| template<class F, class T> | |
| using variant_type = std::conditional_t<false, F, detail::Read<T>>; | |
| public: | |
| template <class... Args> | |
| Wrapper(Args&&... args) | |
| : erased_variant{ A<Args...>(std::forward<Args>(args)...) } { inject_adl_definition<Args...>(); } | |
| template <class F> | |
| void visit(F&& f) { | |
| std::any_cast<variant_type<F, type_tag>&>(erased_variant).visit(std::forward<F>(f)); | |
| } | |
| private: | |
| std::any erased_variant; | |
| }; | |
| int main() { | |
| Wrapper wrapper(9, 8.9, std::string("hello")); | |
| wrapper.visit([](auto&& t) { | |
| std::println("{}", t); | |
| }); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment