C++ 是枚举实现吗
我正在尝试实现C++ 是枚举实现吗,c++,enums,c++11,C++,Enums,C++11,我正在尝试实现std::is_enum。以下是我目前的代码: template<typename T> struct is_enum { static bool value; }; template<typename T> bool is_enum<T>::value = false; template<enum E> struct is_enum { static bool value; }; template<enu
std::is_enum
。以下是我目前的代码:
template<typename T>
struct is_enum {
static bool value;
};
template<typename T>
bool is_enum<T>::value = false;
template<enum E>
struct is_enum {
static bool value;
};
template<enum E>
bool is_enum<E>::value = true;
有人能解释一下我哪里出错了吗?是我的错还是编译器的错?提前谢谢
编辑:如果完全错误,我如何更正
注意:我使用的是g++-o.cpp
这个
template<enum E>
除了没有为变量指定名称之外
从那以后事情就不对劲了。你的问题是
template<enum E>
用
enum E
替换int
,实现这一点的最佳方法是使用编译器魔法,我相信大多数实现都可以做到这一点
例如,这里是libc++对gcc>=4.3的实现,以及任何\u具有\u特性(is\u enum)
1的编译器
template struct\u LIBCPP\u可见是\u enum
:公共积分_常数{};
对于所有其他编译器,libc++执行以下操作:
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 > {};
template struct\u LIBCPP\u可见是\u enum
:公共积分_常数{};
其他一些类型特征仍然需要编译器的魔力。2例如,是union
。但是,可以重写该条件,使其不需要编译器魔法。正如Johannes Schaub指出的那样,这可以通过将对联合和类的单独检查替换为对两者的单独检查来实现
一,。据我所知,不幸的是,只有clang实现了\u\u有功能。
2.有趣的是,libc++确实有一个版本的is_union
和is_class
不使用编译器内部函数,但结果是它们为union类型提供了错误的结果。但是它们的错误结果是互补的,所以libc++的is_enum
的回退实现提供了准确的结果。我相当肯定is_enum
,和许多其他类型特征一样,没有编译器内部函数是无法实现的。[OT]在这种情况下,静态变量的更好替代方法是enum(比如:enum{value=false};
)@Gigi:这被标记为c++11
——最好的选择是从std::true_type
,std::false_type
,或者std::integral_constant
:-]@ildjarn继承,这是不正确的(至少对于c++03来说,我很确定c++11也是如此)。在“C++模板,完整指南”中给出了一个实现,我在我的一个答案中提供了另一个定义(虽然不那么优雅,但通过了所有测试),请参见C++11中的@johanneschaub litb:[meta.rqmts]/p1需要std::is_enum
从std::true_type
或std::false_type
@RondogiannisAristophanes:不,你需要一个编译器内置操作符,就像ildjarn在评论中说的那样。你的答案不正确。在替代定义中,你可以替换!is_union&!is_class
by!is_union\u或_class
,通过尝试形成成员指针并依赖SFINAE,在没有编译器内部函数的情况下实现非常简单。这里提到的所有其他类型训练也可以在没有内部函数支持的情况下编写。@Johannes:Ah,is_union\u或_class
我没有想到。好东西。@bames53:您对libc++何时使用此定义的描述是反向的。libc++将此定义用于gcc<4.3或不具有u has_功能(is_enum)@HowardHinnant我提到了这两种实现,但第一种实现非常简短,很容易跳过。我相信我的回答已经反映出libc++只对gct使用回退。如果编译器内置了nullptr(在这种情况下,可能选择了“magic”版本),那么clang libcxx非magic实现是不正确的。修复它的一种方法是添加&&!is_null_pointer::value
(c++14)。我知道c++14中有此特性,但在最新的libcxx源代码中,它仍然没有修复。
template<enum E>
template<int>
template <class _Tp> struct _LIBCPP_VISIBLE is_enum
: public integral_constant<bool, __is_enum(_Tp)> {};
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 > {};