如何在C中模拟强类型的枚举? [英] How to emulate strongly typed enum in C?

查看:120
本文介绍了如何在C中模拟强类型的枚举?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C ++ 03中,可以模拟强类型枚举将它放在一个类(或命名空间)中:

In C++03, it is possible to emulate strongly typed enum by putting it in a class (or a namespace ) :

struct MyEnum
{
  enum enumName
  {
    VALUE_1 = 1,
    VALUE_2,
  };
};

并使用它:

MyEnum::enumName v = MyEnum::VALUE_1;

可以在C中做类似的事情吗?如果是,如何?

Is it possible to do something similar in C? If yes, how?

我试过这样的,但不行,那不行:

I tried like this, but off course that doesn't work :

struct A
{
  enum aa
  {
    V1 = 5
  };
};

int main()
{
  A::aa a1 = A::V1;
  enum A::aa a2 = A::V1;
  struct A::aa a3 = A::V1;

  return 0;
}


推荐答案

这是我的解决方案。比@ Eric的设计有一些优势:

Here's my solution. Has a few advantages over @Eric's design:


  • 支持等式测试(例如 A_VALUE_0 == value

  • 不依赖C99的复合文字

  • 可以转换为枚举不正确的值。

缺点:


  • 工作(例如 A_VALUE_0 | A_VALUE_1

  • 不能开关'd

  • 可能会在测试平等的错误行时将IDE混淆(例如 A_VALUE_0 == B_VALUE_1

  • Flags do not work (e.g. A_VALUE_0 | A_VALUE_1)
  • Cannot be switch'd
  • Can confuse the IDE on where the error lines are when testing for equality (e.g. A_VALUE_0 == B_VALUE_1)

注意:


  • 不要取消引用此类型的指针。将导致比兰博基尼更快的崩溃

这是实现(使用 -Werror & -pedantic ):

Here's the implementation (compiled with -Werror & -pedantic):

typedef struct A { char empty[1]; } *A; // we use 'empty' so that we don't get a warning that empty structs are a GNU extension
#define A_VALUE_0 ((A) 0x1)
#define A_VALUE_1 ((A) 0x2)
#define A_VALUE_2 ((A) 0x4)

typedef struct B { char empty[1]; } *B;

#define B_VALUE_0 ((B) 0x0)
#define B_VALUE_1 ((B) 0x1)
#define B_VALUE_2 ((B) 0x2)

int main()
{
    A a = A_VALUE_0;

    int equal = (a == A_VALUE_1); // works!
    int euqal = (a == B_VALUE_1) // doesn't work

    A flags = A_VALUE_0 | A_VALUE_1; // doesn't work!

    switch (a) { // doesn't work
        case A_VALUE_0:
            puts("value 0");
            break;
        case A_VALUE_1:
            puts("value 1");
            break;
        case A_VALUE_2:
            puts("value 2");
            break;
        default:
            puts("unknown value");
            break;
    } // doesn't work

    // casting works for assignment:
    A b = (A) (B_VALUE_2);

    return 0;
}

这篇关于如何在C中模拟强类型的枚举?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆