std :: underlying_type:SFINAE会阻止未定义的行为吗?

时间:2016-03-02 11:34:46

标签: c++ c++11 enums undefined-behavior sfinae

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是什么?我怎么能改变它?

2 个答案:

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

Demo

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