如何知道类枚举的基础类型?

时间:2012-02-18 17:19:51

标签: c++ c++11

我有一个变量声明为:

enum class FooEnum: uint64_t {}

我想转换为它的基类型,但我不想硬编码基类型。例如,像这样:

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

这可能吗?

4 个答案:

答案 0 :(得分:35)

您可以使用:

doc说,

  

定义成员typedef类型的类型,它是枚举T的基础类型。

所以你应该能够做到这一点:

#include <type_traits> //include this

FooEnum myEnum;
auto pointer = static_cast<std::underlying_type<FooEnum>::type*>(&myEnum);

答案 1 :(得分:17)

您猜测的语法非常接近。您正在寻找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;
}

答案 2 :(得分:8)

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

答案 3 :(得分:2)

这是另一种不存在underlying_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;