是否有类型特征,或者是否可以编写类型特征is_scoped_enum<T>
:
- if
T
是一个范围枚举,is_scoped_enum<T>::value
istrue
和 - 如果
T
是任何其他类型,is_scoped_enum<T>::value
则为假
是否有类型特征,或者是否可以编写类型特征is_scoped_enum<T>
:
T
是一个范围枚举,is_scoped_enum<T>::value
istrue
和T
是任何其他类型,is_scoped_enum<T>::value
则为假我认为测试它是否是一个枚举并且不能隐式转换为底层类型应该可以解决问题。
template <typename T, bool B = std::is_enum<T>::value>
struct is_scoped_enum : std::false_type {};
template <typename T>
struct is_scoped_enum<T, true>
: std::integral_constant<bool,
!std::is_convertible<T, typename std::underlying_type<T>::type>::value> {};
C++23 将提供is_scoped_enum,一旦实现就可以使用。有关文档,请参阅此链接:is_scoped_enum。我认为 clang 尚不支持此功能(有关支持哪些功能的最新信息,请参阅clang 状态)。
现在我正在使用上面答案的稍微简化的版本(使用 _v 和 _t)以及is_underlying的实现:
// C++ 23 should include 'is_scoped_enum' and 'to_underlying' so the following
// code can be removed:
template<typename T, bool B = std::is_enum_v<T>>
struct is_scoped_enum : std::false_type {};
template<typename T>
struct is_scoped_enum<T, true>
: std::integral_constant<
bool, !std::is_convertible_v<T, std::underlying_type_t<T>>> {};
template<typename T>
inline constexpr bool is_scoped_enum_v = is_scoped_enum<T>::value;
template<typename T, std::enable_if_t<is_scoped_enum_v<T>, int> = 0>
[[nodiscard]] constexpr auto to_underlying(T x) noexcept {
return static_cast<std::underlying_type_t<T>>(x);
}