考虑以下代码:
//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可以被强制转换给一个动物,但是当转换失败时,动物不能成为一个无效的值?
发布于 2018-03-08 23:02:34
如果要进行验证的代码不在代码库的性能关键部分的路径中,则可以使用进行必要验证的函数。
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.
}发布于 2018-03-08 23:05:22
使用既包含枚举值又包含名称的表:
+--------+----------+
| DOG | "DOG" |
+--------+----------+
| CAT | "CAT" |
+--------+----------+
| LLAMA | "llama" |
+--------+----------+
| ALPACA | "alpaca" |
+--------+----------+ 搜索表中的ID。如果存在ID,则可以获取相关的名称。您还可以按名称进行搜索以找到ID。
如果要将ID与名称或名称与ID关联,则可以使用std::map。
https://stackoverflow.com/questions/49183841
复制相似问题