gpt4 book ai didi

c++ - 安全地将整数与强类型枚举进行比较

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:13:07 35 4
gpt4 key购买 nike

当整数值可能不在枚举值范围内时,如何安全地将未知类型的整数值与强类型枚举进行比较?

将整数值与枚举进行比较的最明显方法是将整数值 a 转换为枚举类型 E,然后与枚举值b,像这样:

template <typename I, typename E>
bool compare(I a, E b) { return static_cast<E>(a) == b; }

但是,如果 a 不在枚举值范围内,这将导致未指定的行为,根据 [expr.static.cast]/10:

A value of integral or enumeration type can be explicitly converted to an enumeration type. The value is unchanged if the original value is within the range of the enumeration values (7.2). Otherwise, the resulting value is unspecified (and might not be in that range).

这可以从结果失败中看出(比较,如上):

enum E : uint8_t { A = 0 };
compare(256, E::A); // returns true, 256 == E::A, but E::A = 0

可以将枚举转换为整数类型,但如果整数类型不能表示所有枚举值,这可能会导致不正确的结果:

enum E : int { A = 256 };
template <typename I, typename E>
bool compare(I a, E b) { return a == static_cast<I>(b); }
compare((uint8_t)0); // returns true, 0 == E::A, but E:A = 256

最佳答案

枚举可以转换为其基础整数类型,保证能够表示所有枚举的值。

template <typename I, typename E>
bool compare(I a, E b) { return a == static_cast<std::underlying_type_t<E>>(b); }

如果整数类型和枚举类型的符号不同,通常的算术转换仍然可能存在问题。

enum class : int32_t { A = -1 };
compare(4294967295u, E3::A); // returns true

在这里,E::A = (int32_t)-1转换为 unsigned int , 不能表示 -1,将其转换为(最有可能)4294967295。

只有当一种类型是无符号而另一种具有负值(因此必须是有符号类型)时,才能将整数转换为另一种不能表示其值的整数类型。由于无符号值和负值不可能相等,因此我们无需比较确切值即可知道比较结果。

template <typename I, typename E>
bool compare(I a, E b) {
using UTE = std::underlying_type_t<E>;
return !(std::is_unsigned_v<I> && static_cast<UTE>(b) < 0) &&
!(std::is_unsigned_v<UTE> && a < 0) &&
a == static_cast<UTE>(b);
}

这将正确捕获负值将被转换为无符号值然后可以匹配另一个操作数的情况。由于编译器在编译时知道类型,它可以将符号检查表达式优化为无,a<0 , 或 b<0适用于 a 的类型和 b .

关于c++ - 安全地将整数与强类型枚举进行比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47616002/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com