std::underlying_type
在与非枚举类型一起使用时调用未定义的行为。
但是未定义的行为出现在哪里?
在此代码中:
template<typename E>
constexpr std::enable_if_t<std::is_enum<E>::value, std::underlying_type_t<E>> IntEnum(E e)
{
return static_cast<std::underlying_type_t<E>>(e);
}
我尝试使用std::enable_if
来阻止用户使用非枚举类型调用IntEnum
。但是,在决定是否可以调用函数之前评估enable_if
,其模板参数也会被评估,包括std::underlying_type_t<E>
。如果用非枚举类型调用,那么这个UB是什么?我怎么能改变它?
答案 0 :(得分:2)
typename std::underlying_type<E>::type
即使对于非枚举类型也会被评估(并且不是SFINAE友好的)。
您可以使用一个间接延迟评估并且SFINAE友好:
template<typename E>
constexpr
typename std::enable_if_t<std::is_enum<E>::value, std::underlying_type<E>>::type
IntEnum(E e)
{
return static_cast<std::underlying_type_t<E>>(e);
}
答案 1 :(得分:0)
您可以使用static_assert
template<typename E>
constexpr auto IntEnum(E e)
{
static_assert(std::is_enum<E>::value, "E must be an enum");
return static_cast<std::underlying_type_t<E>>(e);
}