首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我如何干净地验证并转换为不连续的枚举?

我如何干净地验证并转换为不连续的枚举?
EN

Stack Overflow用户
提问于 2018-03-08 22:52:53
回答 2查看 96关注 0票数 1

考虑以下代码:

代码语言:javascript
复制
//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;

我的应用程序将收到一些数据,我想知道它所指的是哪个动物。

代码语言:javascript
复制
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++还不太了解,不知道如何做到这一点:

代码语言:javascript
复制
//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可以被强制转换给一个动物,但是当转换失败时,动物不能成为一个无效的值?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-03-08 23:02:34

如果要进行验证的代码不在代码库的性能关键部分的路径中,则可以使用进行必要验证的函数。

代码语言:javascript
复制
std::pair<bool, Animal> getAnimal(int data)
{
   switch (data)
   {
      case Animal::DOG
        return {true, Animal::DOG};

      ...

      default:
   }

   return {false, ANIMAL::DOG};
}

并将其用作:

代码语言:javascript
复制
auto res = getAnimal(data);
if ( res.first )
{
   // Valid data.
   // Use res.second.
}
else
{
   // Deal with invalid data.
}
票数 0
EN

Stack Overflow用户

发布于 2018-03-08 23:05:22

使用既包含枚举值又包含名称的表:

代码语言:javascript
复制
+--------+----------+  
| DOG    | "DOG"    |  
+--------+----------+  
| CAT    | "CAT"    |  
+--------+----------+  
| LLAMA  | "llama"  |  
+--------+----------+  
| ALPACA | "alpaca" |  
+--------+----------+  

搜索表中的ID。如果存在ID,则可以获取相关的名称。您还可以按名称进行搜索以找到ID。

如果要将ID与名称或名称与ID关联,则可以使用std::map

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49183841

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档