is_enum implementation

后端 未结 3 1393
伪装坚强ぢ
伪装坚强ぢ 2021-02-05 07:44

I\'m trying to implement std::is_enum. Here is my code so far:

template
struct is_enum {
    static bool value;
};

template

        
相关标签:
3条回答
  • 2021-02-05 08:20

    The best way to implement this is to use compiler magic, and I believe most implementations do this.

    For example, here's libc++'s implementation for gcc >= 4.3 and any compiler that __has_feature(is_enum)1

    template <class _Tp> struct _LIBCPP_VISIBLE is_enum
        : public integral_constant<bool, __is_enum(_Tp)> {};
    



    For all other compilers libc++ does:

    template <class _Tp> struct _LIBCPP_VISIBLE is_enum
        : public integral_constant<bool, !is_void<_Tp>::value             &&
                                         !is_integral<_Tp>::value         &&
                                         !is_floating_point<_Tp>::value   &&
                                         !is_array<_Tp>::value            &&
                                         !is_pointer<_Tp>::value          &&
                                         !is_reference<_Tp>::value        &&
                                         !is_member_pointer<_Tp>::value   &&
                                         !is_union<_Tp>::value            &&
                                         !is_class<_Tp>::value            &&
                                         !is_function<_Tp>::value         > {};
    

    Some of those other type traits still require compiler magic.2 E.g. is_union. However, that condition can be rewritten such that it doesn't need compiler magic. This can be done by replacing the seperate checks for unions and classes with a single check for both, as Johannes Schaub points out.

    1. So far as I know only clang implements __has_feature, unfortunately.
    2. It's interesting that libc++ does have a version of is_union<T> and is_class<T> that do not use compiler intrinsics, but as a result they provide erroneous results for union types. But their erroneous results are complementary so libc++'s fallback implementation of is_enum<T> provides accurate results.

    0 讨论(0)
  • 2021-02-05 08:23

    You problem is that

    template<enum E>
    

    Is interpreted as unnamed parameter with type forward declared enum named E.
    Semantically same to

    template<int>
    

    Just substituting int with enum E.

    0 讨论(0)
  • 2021-02-05 08:39

    This

    template<enum E>
    

    promises that the template argument is a value of type enum E. The argument is NOT a type (Type template arguments are introduced by typename, or for backward compatibility, class. Even struct isn't allowed). It's just like saying

    template<int i>
    

    except no name is given for the variable.

    Things go wrong from there.

    0 讨论(0)
提交回复
热议问题