Как узнать базовый тип класса enum? - PullRequest
29 голосов
/ 18 февраля 2012

У меня есть переменная, объявленная как:

enum class FooEnum: uint64_t {}

и я хотел бы привести его к базовому типу, но я не хочу жестко кодировать базовый тип. Например, что-то вроде этого:

FooEnum myEnum;
uint64_t * intPointer = (underlying_typeof(myEnum))&myEnum;

Возможно ли это?

Ответы [ 4 ]

35 голосов
/ 18 февраля 2012

Вы можете использовать это:

  • std::underlying_type шаблон класса для определения базового типа перечисления.

документ говорит,

Определяет элемент typedef тип тип , который является базовым типом для перечисления T.

Так что вы должны быть в состоянии сделать это:

#include <type_traits> //include this

FooEnum myEnum;
auto pointer = static_cast<std::underlying_type<FooEnum>::type*>(&myEnum);
17 голосов
/ 18 февраля 2012

Ваш угаданный синтаксис удивительно близок.Вы ищете std::underlying_type в <type_traits>:

#include <type_traits>
#include <cstdint>

enum class FooEnum: std::uint64_t {};

int main()
{
    FooEnum myEnum;
    uint64_t* intPointer = (std::underlying_type<FooEnum>::type*)&myEnum;
}
8 голосов
/ 09 июня 2012

В Visual C ++ 10.0 и MinGW g ++ 4.6.1 не хватает std::underlying_type, но оба принимают этот код:

template< class TpEnum >
struct UnderlyingType
{
    typedef typename conditional<
        TpEnum( -1 ) < TpEnum( 0 ),
        typename make_signed< TpEnum >::type,
        typename make_unsigned< TpEnum >::type
        >::type T;
};
2 голосов
/ 31 июля 2012

Вот еще один подход, когда базовый_тип отсутствует. Этот метод не пытается обнаружить подпись перечисления, просто дает вам тип того же размера, которого более чем достаточно для многих ситуаций.

template<int>
class TIntegerForSize
{
    typedef void type;
};

template<>
struct TIntegerForSize<1>
{
    typedef uint8_t type;
};

template<>
struct TIntegerForSize<2>
{
    typedef uint16_t type;
};

template<>
struct TIntegerForSize<4>
{
    typedef uint32_t type;
};

template<>
struct TIntegerForSize<8>
{
    typedef uint64_t type;
};

template<typename T>
struct TIntegerForEnum
{
    typedef typename TIntegerForSize<sizeof(T)>::type type;
};

Использование:

enum EFoo {Alpha, Beta};
EFoo f = Alpha;
TIntegerForEnum<EFoo>::type i = f;
TIntegerForEnum<decltype(f)>::type j = f;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...