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

std::underlying_type : Does SFINAE prevent undefined behavior?

本文关键字:未定义 是否 underlying type SFINAE std      更新时间:2023-10-16
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 是否?如何更改它?

即使

对于非枚举类型(并且对SFINAE不友好),也会评估typename std::underlying_type<E>::type

您可以使用一个间接通道来延迟评估并友好地对 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);
}

演示

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