如何限制从int到enum类的转换
How to restrict conversion from int to enum class?
如果我有这样的enum class
:
enum class Weekday {
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
}
并且我有从int
到Weekday
:的转换
Weekday day = static_cast<int>(value);
为了检查为转换提供的值是否有效,我应该有代码:
if (value != 0 && value != 1 && value !=2 && value !=3 && value != 4 && value != 5 && value != 6) {
do_conversion(value);
}
太难看了。有什么好方法可以做到这一点吗?
这可能使表面上的事情过于复杂,但它概括得很好,模板voodoo可以隐藏在一个看不见的标题中。
#include <stdexcept>
template <class TYPE>
TYPE do_conversion(int value)
{
if (value >= static_cast<int>(TYPE::First) &&
value < static_cast<int>(TYPE::Last))
{
return static_cast<TYPE>(value);
}
throw std::out_of_range("Inv value");
}
所有的转换都移动到一个函数中,以降低噪声。使用额外的枚举值First and Last
来抽象有效范围。如果给定的值在(First
,Last
](范围内,则赋值。如果不在,则抛出异常。根据无效输入的频率,异常可能不是正确的做法,如果错误输入很常见,则很难成为异常,但在这里,它有助于保持示例的简单性。
现在调用是的一个简单问题
enum class Weekday
{
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday,
Last, // added
First = Monday // added
};
以及后来的
Weekday day = do_conversion<Weekday>(value);
转换过程中产生的所有噪音都妨碍了转换所需的一切,所以无论是谁在读或写这段代码,都可以继续他们的工作。
但是,如果您在没有First
和Last
的enum
上使用它呢?编译器消息可能会变得奇怪,所以最好帮用户一点忙。以下内容已从"如何检测类中是否存在特定的成员变量?"?让它更容易使用。一定要花点时间阅读答案,了解发生了什么。我还没有想出一个将HasFirst
和HasLast
结合起来的好方法。如果你有评论,请留言告诉我。
#include <stdexcept>
#include <type_traits>
template <typename T, typename = int>
struct HasFirst : std::false_type { };
template <typename T>
struct HasFirst <T, decltype((void) T::First, 0)> : std::true_type { };
template <typename T, typename = int>
struct HasLast : std::false_type { };
template <typename T>
struct HasLast <T, decltype((void) T::Last, 0)> : std::true_type { };
template <class TYPE>
TYPE do_conversion(int value)
{
static_assert(HasFirst<TYPE>::value, "enum missing First");
static_assert(HasLast<TYPE>::value, "enum missing Last");
if (value >= static_cast<int>(TYPE::First) &&
value < static_cast<int>(TYPE::Last))
{
return static_cast<TYPE>(value);
}
throw std::out_of_range("Inv value");
}
现在,如果enum
缺少最重要的元值,编译器可以通过一条简单的错误消息告诉它们。
测试用例
枚举类的默认基础类型是integer。因此,要检查一个整数是否在可接受的枚举值范围内,可以使用static_cast<int>
:将其与可接受枚举值的边界进行比较
if (value >= static_cast<int>(Weekday::Monday) && value <= static_cast<int>(Weekday::Sunday))
{
do_conversion(value);
}
相关文章:
- enum是C++中的宏变量还是整数变量
- 防止主数据类型C++的隐式转换
- 模板参数替换失败,并且未完成隐式转换
- 努力将整数转换为链表。不知道我在这里做错了什么
- HEX值到wchar_t字符(UTF-8)的转换
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将 Qvector<uint8_t> 转换为 QString
- 是否可以从int转换为enum类类型
- 如何限制从int到enum类的转换
- 为什么C/C++会自动将char/wchar_t/short/bool/enum类型转换为int
- snprintf变量列表不会将enum转换为char*
- 在QTableView中将数据从QSqlTableModel转换为人类形式(enum -> String)
- 将Enum转换为布尔类型
- 转换c++中enum变量中的字符串变量
- 对整型到enum的转换进行Static_cast
- 是否可以使作用域枚举("enum class")在上下文中可转换为布尔值?
- 将enum强制转换为整型
- c++不能从enum转换为LPCTSTR
- 为什么enum隐式地转换为std::string ?
- 安全地将int转换为enum