Как узнать базовый тип перечисления класса?
У меня есть переменная, объявленная как:
enum class FooEnum: uint64_t {}
и я хотел бы использовать его базовый тип, но я не хочу жестко задавать базовый тип. Например, что-то вроде этого:
FooEnum myEnum;
uint64_t * intPointer = (underlying_typeof(myEnum))&myEnum;
Возможно ли это?
Ответы
Ответ 1
Вы можете использовать это:
doc говорит,
Определяет тип элемента typedef
типа, который является базовым типом для перечисления T.
Итак, вы должны это сделать:
#include <type_traits> //include this
FooEnum myEnum;
auto pointer = static_cast<std::underlying_type<FooEnum>::type*>(&myEnum);
Ответ 2
Ваш угаданный синтаксис поразительно близок. Вы ищете 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;
}
Ответ 3
Оба Visual С++ 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;
};
Ответ 4
Вот еще один подход, когда base_type отсутствует. Этот метод не пытается обнаружить подписанность перечисления, просто дайте вам тип того же размера, которого более чем достаточно для множества ситуаций.
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;