如何在C/C++中具有多个相似值的枚举上切换()?

Fur*_*rge 4 c enums

让我们说我有一个枚举:

typedef enum
{
    gray = 4, //Gr[ae]y should be the same
    grey = 4,
    blue = 5,
    red  = 6
} FOO;
Run Code Online (Sandbox Code Playgroud)

然后我想打开这个:

switch(f){
    case gray:
    case grey:
        printf("The color of an elephant\n"); break;
    case blue:
        printf("The color of the sky\n"); break;
    case red:
        printf("The color of an apple\n"); break;
    default:
        printf("I don't know this color\n"); 
 }
Run Code Online (Sandbox Code Playgroud)

基本上我有枚举,其值基本上是我想要以完全相同的方式处理的同义词.我尝试了上面的开关,但它不能为我编译.有没有办法做到这一点,还是我坚持使用if/else逻辑?(我不愿意,因为有20多个枚举,而且开关看起来更干净

编辑:是的,我知道我可以选择其中一个(并且没有区域设置不是解决方案),但是枚举明确允许您声明重复值然后您无法使用它似乎有点奇怪他们在转换声明?我想使用枚举,以便我可以在库API中静态强制执行它们发送正确的值(是的,我知道你可以绕过类型转换,我只是想防止愚蠢的错误等等).如果我这样做,现在看来我失去了在switch语句中使用它的能力.

编译器只是将逻辑简化为if/else逻辑.如果案例4:案例5:bar(); 打破;

是合法的,为什么不能案例4:案例4:bar(); 打破;

合法吗?编译器应该能够将其优化为一个语句并继续前进.

Kei*_*son 7

你不能.

C标准要求case给定switch语句的标签中的所有常量表达式具有不同的值.这在编译时检查.具有case相同值的两个标签是违反约束,需要编译时诊断.(这可能是一个非致命的警告,但我不知道任何编译器不会将其视为致命错误.)

该规则在N1570 6.8.4.2p3中说明:

每个case标签的表达式应为整数常量表达式,并且case同一switch语句中的两个常量表达式在 转换后不应具有相同的值.

C++有类似的规则.

这意味着,例如:

switch (blah) {
    case 2+2:
    case 4:
        /* ... */
}
Run Code Online (Sandbox Code Playgroud)

也是非法的.编译器检查表达式的,无论它们是否对人类读者具有某些不同的含义.

你只需要选择gray或者grey.

(原则上,标准可以允许两个案例标签具有相同的值,只要它们被组合在一起,就像在你的例子中一样.但它没有这样定义,可能是因为它被认为不够有用. )

  • @FuriousGeorge:这是一个不同的问题.随意发布它(虽然它可能被关闭为"主要基于意见").我认为答案基本上就是那不是*唯一的东西枚举用于. (2认同)