我有一个事件处理程序类,该类使用模板参数来设置事件类型。我想将这些事件类型强制为一个字节大小的枚举类。针对大小的静态断言不是问题,但是我无法在线找到有关如何静态区分 enum 和 enum类的信息。
我现在的解决方案是使用C++ front-end implements syntactic extensions声明枚举,然后声明正确的大小。在大多数平台上,这是可行的,因为枚举使用int
类型(通常大于一个字节)。
但是这会导致误导一些错误消息。我想做到透彻。
我可以通过类枚举执行哪些检查,但由于常规旧枚举而失败?
我不能使用type_traits
,因为我使用的编译器( avr-gcc )不支持它。但是,当需要增加时,我会不断实施自己的type_traits
。因此,type_traits
中有关解决方案的任何提示仍然有用!
最小示例:
// Event types
enum class tPass : uint8_t {};
enum class tFailSize : uint16_t {}; // Fail on size!
enum tFailType {}; // Currently fails on size, would like to fail on type!
// Event handler
template <typename TEvent>
class tEventHandler
{
static_assert(__is_enum(TEvent), "Must be class enum!"); // Doesn't really check for CLASS enums
static_assert(1 == sizeof(TEvent), "Must be one byte!");
};
用法:
auto handler = tEventHandler<tPass>(); // Ok!
// auto handler2 = tEventHandler<tFailSize>(); // error: static assertion failed: Must be one byte!
// auto handler3 = tEventHandler<tFailType>(); // error: static assertion failed: Must be one byte! <----- THIS
目标:
auto handler = tEventHandler<tPass>(); // Ok!
// auto handler2 = tEventHandler<tFailSize>(); // error: static assertion failed: Must be one byte!
// auto handler3 = tEventHandler<tFailType>(); // error: static assertion failed: Must be class enum! <--- THIS
答案 0 :(得分:6)
未定义范围的枚举与范围类型(enum class
)之间的主要区别在于,前者隐式转换为其基础类型,而后者则隐式转换为它们的基础类型。由于您对type_traits
解决方案的外观感兴趣,因此可以进行检查(未完全测试,可能对SFINAE不友好):
static_assert(std::is_enum<TEvent>::value, "Must be a scoped enum!");
static_assert(!std::is_convertible<TEvent, typename std::underlying_type<TEvent>::type>::value,
"Must be a scoped enum!");
如果AVR-GCC具有underlying_type
内在函数,则只需补充is_convertible
特性(甚至可以在C ++ 03中实现)。