Search code examples
c++typestype-traits

How to get the class type of an unnamed struct in a typedef inside the unnamed class?


This is a theoritcal question whether it is possible to get the type of the unnamed struct inside its definition.



int main() {
   struct {
         using ThisType = ???? //what do i put here?
    } _; // the instance
}

I tried to extract the class from a member finction pointer but it didnt work

template<typename>
struct get_class;

template<typename Class>
struct get_class<void(Class::*)()>{using type = Class;};

int main(){
struct {
    void getThis(){}
    using ThisType = typename get_class<decltype(getThis)>::type; // error cant know which function to call to determine 
    // i tried to static_cast but I need to know the class type still.
} _;
}

Is it even possible?


Solution

  • I wrote a library to be able to do this in a macro without naming the current type: https://godbolt.org/z/ja77Kzz9q. It works in this context too.

    Here's a stripped down version with just the parts you need:

    #include <type_traits>
    
    namespace detail {
    template<typename Tag>
    struct retrieve_type {
        constexpr friend auto friend_function(retrieve_type<Tag>);
        constexpr auto member_function() {
            return friend_function(*this);
        }
    };
    
    template<typename Tag, typename Stored>
    struct store_type {
        constexpr friend auto friend_function(retrieve_type<Tag>) {
            return std::type_identity<Stored>{};
        }
    };
    }
    
    int main() {
        struct {
        private:
            struct tag_type;
            auto storer() -> decltype(detail::store_type<tag_type, decltype(this)>{});
        public:
            using ThisType = std::remove_pointer_t<decltype(detail::retrieve_type<tag_type>{}.member_function())::type>;
        } _; // the instance
        static_assert(std::is_same_v<decltype(_)::ThisType, decltype(_)>);
    }
    

    This uses template metaprogramming to store the type of this available in the scope of the trailing return type and then retrieves it later.