std::underlying_type : SFINAE 是否防止未定义的行为?

std::underlying_type : Does SFINAE prevent undefined behavior?

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 是吗?我该如何更改它?

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);
}

Demo

您可以使用 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);
}