字符串到枚举的失败证明转换 class
fail proof conversion of string to enum class
我有一个像这样的枚举 class(我打算稍后添加更多选项):
enum class ViSequencePointType {
JumpToValue = 0,
RampToValue = 1
};
然后我有一个配置文本文件,其中每一行都应该代表一个枚举值。像这样:
1
0
255
A
WTF
我需要解析此文件并创建该枚举的向量 class...所以我会执行以下操作:
bool conversionResult = false;
int colThree = line.toInt(&conversionResult);
if(!conversionResult) {
//failed to convert to integer
} else {
ViSequencePointType pt = static_cast<ViSequencePointType>(colThree);
switch(pt) {
case ViSequencePointType::JumpToValue:
break;
case ViSequencePointType::RampToValue:
break;
default:
break;
}
对于 default
的情况,编译器说
Default label in switch which covers all enumeration values
我相信这意味着如果文本文件中存在任何无效条目,我找不到它!
那么如何在 运行时 期间不让任何无效枚举溜走的情况下解决这个问题?
为了覆盖 invalid/nonsensical 枚举值,通常的做法是
- 基于以下事实,后续枚举值被隐式分配为前一个枚举值的值 + 1
- 在枚举中的最低值处添加一个
"Invalid"
枚举值(隐式为 0,或者您可以为其分配一个较低的值,例如 -1
)
- 在枚举中的最高值处添加一个
"Max"
枚举值
这是一个例子:
enum class ViSequencePointType
{
Invalid = -1,
JumpToValue, // is implicitly assigned enum value 0 (-1 + 1 == 0)
RampToValue, // is implicitly 1 (JumpToValue + 1)
CrawlToValue, // etc...
HopToValue,
// add new values here
Max // Max must be the last value in the enum
};
现在,当您解析输入值时,您可以检查整数值是否大于 Invalid
且小于 Max
,如果是这样,您就知道它是一个有效的枚举值
ViSequencePointType parse(const std::string& value)
{
bool converted = false;
int val = line.toInt(&converted);
if(!converted)
{
// do additional conversion failure handling here if necessary
return ViSequencePointType::Invalid;
}
if (val <= static_cast<int>(ViSequencePointType::Invalid) ||
val >= static_cast<int>(ViSequencePointType::Max)
{
// do additional out of bounds handling here if necessary
return ViSequencePointType::Invalid;
}
return static_cast<ViSequencePointType>(val);
}
现在您知道 parse
的输出是一个有效的枚举值,unknown/invalid 值的输出由枚举值 Invalid
.
表示
我有一个像这样的枚举 class(我打算稍后添加更多选项):
enum class ViSequencePointType {
JumpToValue = 0,
RampToValue = 1
};
然后我有一个配置文本文件,其中每一行都应该代表一个枚举值。像这样:
1
0
255
A
WTF
我需要解析此文件并创建该枚举的向量 class...所以我会执行以下操作:
bool conversionResult = false;
int colThree = line.toInt(&conversionResult);
if(!conversionResult) {
//failed to convert to integer
} else {
ViSequencePointType pt = static_cast<ViSequencePointType>(colThree);
switch(pt) {
case ViSequencePointType::JumpToValue:
break;
case ViSequencePointType::RampToValue:
break;
default:
break;
}
对于 default
的情况,编译器说
Default label in switch which covers all enumeration values
我相信这意味着如果文本文件中存在任何无效条目,我找不到它!
那么如何在 运行时 期间不让任何无效枚举溜走的情况下解决这个问题?
为了覆盖 invalid/nonsensical 枚举值,通常的做法是
- 基于以下事实,后续枚举值被隐式分配为前一个枚举值的值 + 1
- 在枚举中的最低值处添加一个
"Invalid"
枚举值(隐式为 0,或者您可以为其分配一个较低的值,例如-1
) - 在枚举中的最高值处添加一个
"Max"
枚举值
这是一个例子:
enum class ViSequencePointType
{
Invalid = -1,
JumpToValue, // is implicitly assigned enum value 0 (-1 + 1 == 0)
RampToValue, // is implicitly 1 (JumpToValue + 1)
CrawlToValue, // etc...
HopToValue,
// add new values here
Max // Max must be the last value in the enum
};
现在,当您解析输入值时,您可以检查整数值是否大于 Invalid
且小于 Max
,如果是这样,您就知道它是一个有效的枚举值
ViSequencePointType parse(const std::string& value)
{
bool converted = false;
int val = line.toInt(&converted);
if(!converted)
{
// do additional conversion failure handling here if necessary
return ViSequencePointType::Invalid;
}
if (val <= static_cast<int>(ViSequencePointType::Invalid) ||
val >= static_cast<int>(ViSequencePointType::Max)
{
// do additional out of bounds handling here if necessary
return ViSequencePointType::Invalid;
}
return static_cast<ViSequencePointType>(val);
}
现在您知道 parse
的输出是一个有效的枚举值,unknown/invalid 值的输出由枚举值 Invalid
.