Как я могу получить основной тип перечисления? - PullRequest
10 голосов
/ 28 октября 2011

С декларацией, такой как:

enum DrawBoldMode : unsigned
{
    DBM_NONE =              0,
    DBM_ITEM =              1<<0,   // bold just the nearest line
    DBM_SECTION =           1<<1,   // bold all lines in the same section
    DBM_LINETYPE =          1<<2,   // bold all lines of the same line type
    DBM_POINTAGE =          1<<3,   // bold all lines of the same line type
};

Как я могу получить базовый тип DrawBoldMode (т.е. без знака)?

Ответы [ 2 ]

12 голосов
/ 28 октября 2011

std::underlying_type доступен в GCC 4.7, но до этого вы можете получить приблизительную эмуляцию с шаблонами :

#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> {};
}

Он не дает вам точный тип, но он дает вам тот же размер и характеристики подписи.

7 голосов
/ 28 октября 2011

Должен быть доступен как std::underlying_type<DrawBoldMode>::type.Однако мой компилятор (GCC 4.6.1), похоже, не реализует это.

Я думаю невозможно реализовать его с помощью шаблонов, но я могу ошибаться.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...