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 是否?如何更改它?
即使
对于非枚举类型(并且对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);
}
相关文章:
- 不知道某个东西是否被忽略会引入未定义的行为吗
- 此增量后语句是否会导致未定义的行为?
- Windows 链接器是否使用 LoadLibrary 解析 DLL 中未定义的符号?
- 如何测试 size_t -1 是否未定义,其中 size_t 为 0?
- 在销毁期间从另一个线程调用对象上调用方法是否未定义行为?
- 从 std::string 到 std::array<char,size> 的 memcopy 额外数据是否是一种未定义的行为?
- 负指数是否必然意味着未定义的行为
- 在"printf"中使用标签"h"或"hh"是否涉及未定义的
- 在 C++17 中,是否未定义使用无锁原子学保护从信号处理程序传递的数据?
- C++ 如何检查 char 变量是否未定义(未初始化)
- 递减 std::vector::begin 是否未定义,即使它从未被使用过?
- 访问从联合与另一个成员集复制的联合中的一个成员是否未定义或未指定?
- 在C++中,转换为simd类型是否有未定义的行为
- 是否是从等待返回到悬而未决的"this"实例的未定义行为?
- 是否未定义将对函数范围变量的引用作为值返回
- FBString 的小字符串优化是否依赖于未定义的行为?
- 移动 std::bitset<N> 是否超过 N 个位置未定义的行为?
- 创建指针是否超过非数组指针的末尾,而不是从 C++17 中的一元运算符和未定义的行为派生?
- 使用c_str是否有未定义的异常行为
- i=i++;未定义.是否i=foo(i++)也未定义