Search code examples
c++typesenumsreturnconstexpr

Return variable type along an enum c++


I needed it for a socket buffer that I'm making (reading and writing...), this is more a trick than anything else so I would like to know if there is a better way of doing it with the current c++ features/standards? I'm sure of it.

enum e_Types
{
    Type_64 ,
    Type_32 ,
    Type_16 ,
    Type_8 ,
    Type_ALL
};

template<e_Types Type> constexpr auto _GetVarType()
{
    if constexpr( Type == Type_8 )
        return ( unsigned char* ) 0;
    if constexpr( Type == Type_16 )
        return ( unsigned short* ) 0;
    if constexpr( Type == Type_32 )
        return ( unsigned long* ) 0;
    if constexpr( Type == Type_64 )
        return ( unsigned long long* ) 0;
}

#define GetVarType(type) decltype( _GetVarType<type>() )

Example:

GetVarType( Type_64 ) p64 = malloc(0x1000);

Thanks for replies.


Solution

  • You can use good old explicit template class specialization:

    template <e_Types X> struct type_of;
    template <>          struct type_of<Type_64> { using type = unsigned long long; };
    template <>          struct type_of<Type_32> { using type = unsigned long; };
    template <>          struct type_of<Type_16> { using type = unsigned short; };
    template <>          struct type_of<Type_8>  { using type = unsigned char; };
    
    template <e_Types X> 
    using type_of_t = typename type_of<X>::type;
    

    Usage:

    type_of_t<Type_64>* p64 = malloc(0x1000);
    

    If you want to go down the constexpr-based route, you can do something like:

    template <typename T> 
    struct type_wrapper 
    { 
        using type = T; 
    };
    
    template <typename T> 
    inline constexpr type_wrapper<T> t{};
    
    template <e_Types X> inline constexpr auto type_of          = t<void>;
    template <>          inline constexpr auto type_of<Type_64> = t<unsigned long long>;
    template <>          inline constexpr auto type_of<Type_32> = t<unsigned long>;
    template <>          inline constexpr auto type_of<Type_16> = t<unsigned short>;
    template <>          inline constexpr auto type_of<Type_8>  = t<unsigned char>;
    

    Usage:

    typename decltype(type_of<Type_64>)::type* p64 = malloc(0x1000);
    

    But I don't find this superior to the more traditional approach.