请考虑以下代码:
//Note that the enum is nonsequential. I don't have control of
//this enum so I cannot change it to be sequential
enum class Animal {
DOG = 0,
CAT = 1,
LLAMA = 20,
ALPACA = 21,
};
//This data is received as an int,
//but I want to know what Animal it refers to
int data_0 = 0;
int data_2 = 2;
我的应用程序将收到一些数据,我想知道它引用的是哪种动物。
Animal foo = static_cast<Animal>(data_0); //Great, it's an Animal::DOG.
Animal bar = static_cast<Animal>(data_2); //Whoops! This will crash.
if (foo == Animal::DOG) { //This is an easy comparison
//do something
}
显然,我需要对传入的数据进行一些验证,否则我会冒着崩溃的风险。
对我而言,似乎解决方案是在演示枚举时进行显式验证,但我不太了解C ++以了解干净的方法:
//This is not sufficient to validate the value
if (data_2 > Animal::DOG && data_2 < Animal::ALPACA) {
Animal bar = static_cast<Animal>(data_2); //Whoops! This will crash.
}
//This is sufficient to validate the value, but is very ugly
Animal bar;
if (data_2 == static_cast<int>(Animal::DOG) ||
data_2 == static_cast<int>(Animal::CAT) ||
data_2 == static_cast<int>(Animal::LLAMA) ||
data_2 == static_cast<int>(Animal::ALPACA)) {
bar = static_cast<Animal>(data_2); //This does not run because of the checking
}
//bar was not assigned, so it would be NULL or 0
if (bar == Animal::DOG) {
//oh no, we shouldn't be here!
}
必须有更好的方法来做到这一点,所以我觉得我错过了一些东西。我怎么能设计这样做,以便可以将一个int强制转换为Animal,但是当转换失败时,Animal不会最终成为无效值?
答案 0 :(得分:0)
如果执行验证的代码不在代码库的性能关键部分的路径中,则可以使用执行必要验证的函数。
std::pair<bool, Animal> getAnimal(int data)
{
switch (data)
{
case Animal::DOG
return {true, Animal::DOG};
...
default:
}
return {false, ANIMAL::DOG};
}
并将其用作:
auto res = getAnimal(data);
if ( res.first )
{
// Valid data.
// Use res.second.
}
else
{
// Deal with invalid data.
}
答案 1 :(得分:0)
使用包含枚举值和名称的表:
+--------+----------+
| DOG | "DOG" |
+--------+----------+
| CAT | "CAT" |
+--------+----------+
| LLAMA | "llama" |
+--------+----------+
| ALPACA | "alpaca" |
+--------+----------+
在表格中搜索ID。如果ID存在,您可以获取关联的名称。您还可以按名称搜索以查找ID。
如果要将ID与名称或名称与ID相关联,则可以使用std::map
。