How do I get the fundamental type of an enum?

后端 未结 2 1978
花落未央
花落未央 2021-01-04 10:39

With a declaration such as:

enum DrawBoldMode : unsigned
{
    DBM_NONE =              0,
    DBM_ITEM =              1<<0,   // bold just the nearest          


        
相关标签:
2条回答
  • 2021-01-04 11:08

    It should be available as std::underlying_type<DrawBoldMode>::type. However, my compiler (GCC 4.6.1) doesn't seem to implement that.

    I think it's impossible to implement it with templates, but I could be wrong about that.

    0 讨论(0)
  • 2021-01-04 11:12

    std::underlying_type is available in GCC 4.7, but until then you can get an approximate emulation with templates:

    #include <tuple>
    // This is a hack because GCC 4.6 does not support std::underlying_type yet.
    // A specialization for each enum is preferred
    namespace detail {
        template <typename T, typename Acc, typename... In>
        struct filter;
    
        template <typename T, typename Acc>
        struct filter<T, Acc> {
            typedef typename std::tuple_element<0, Acc>::type type;
        };
    
        template <typename T, typename... Acc, typename Head, typename... Tail>
        struct filter<T, std::tuple<Acc...>, Head, Tail...>
        : std::conditional<sizeof(T) == sizeof(Head) && (T(-1) < T(0)) == (Head(-1) < Head(0))
                          , filter<T, std::tuple<Acc...,Head>, Tail...>
                          , filter<T, std::tuple<Acc...>, Tail...>
                          >::type {};
    
        template <typename T, typename... In>
        struct find_best_match : filter<T, std::tuple<>, In...> {};
    }
    
    namespace std {
        template <typename E>
        struct underlying_type : detail::find_best_match<E,
                                    signed short,
                                    unsigned short,
                                    signed int,
                                    unsigned int,
                                    signed long,
                                    unsigned long,
                                    signed long long,
                                    unsigned long long,
                                    bool,
                                    char,
                                    signed char,
                                    unsigned char,
                                    wchar_t,
                                    char16_t,
                                    char32_t> {};
    }
    

    It doesn't give you the exact type, but it gives you one with the same size and signedness characteristics.

    0 讨论(0)
提交回复
热议问题