【问题标题】:How do I get the fundamental type of an enum?如何获得枚举的基本类型?
【发布时间】:2011-10-28 15:26:52
【问题描述】:

带有如下声明:

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^0 是 2 XOR 0。我相信你想要 (1
  • 这似乎不可能,模板或其他。
  • 我不认为可以做到,除非所有底层类型都是唯一的大小。
  • D'oh-我永远忘记了 C++ 中的 x^y 是 xor not power。叹息...:P

标签: c++ templates c++11


【解决方案1】:

std::underlying_type 在 GCC 4.7 中可用,但在那之前你可以得到一个近似的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> {};
}

它不会为您提供确切的类型,但它会为您提供具有相同大小和签名特征的类型。

【讨论】:

【解决方案2】:

它应该以std::underlying_type&lt;DrawBoldMode&gt;::type 的形式提供。但是,我的编译器(GCC 4.6.1)似乎没有实现。

认为不可能用模板来实现它,但我可能错了。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2012-03-09
  • 1970-01-01
  • 1970-01-01
  • 2017-01-14
  • 2014-07-23
  • 1970-01-01
相关资源
最近更新 更多