Using C flag enums in C++

前端 未结 5 503
时光说笑
时光说笑 2020-12-16 15:51

I have a C API that defines an enum like so:

typedef enum
{
  C_ENUM_VALUE_NONE    = 0,
  C_ENUM_VALUE_APPLE   = (1 << 0),
  C_ENUM_VALUE_BANANA  = (1          


        
相关标签:
5条回答
  • 2020-12-16 16:28

    By or-ing two enum values, you're creating an invalid value (0x3 is not in enum CEnumType). Enumerations are not bitfields. If you want a bitfield, define one.

    You can cast the value if you want to force it through, but that may surprise some code that is counting on only being able to get the enumerated values.

    do_something((CEnumType)(C_ENUM_VALUE_APPLE | C_ENUM_VALUE_BANANA));
    
    0 讨论(0)
  • 2020-12-16 16:37

    In the case of bitwise operations, the expression evaluates to a primitive type, i.e. int, long, etc. However, your function takes a non-primitive type (CEnumType). The only way I know of to bypass this is to cast the expression. For example:

    do_something((CEnumType) (C_ENUM_VALUE_APPLE | C_ENUM_VALUE_BANANA));
    
    0 讨论(0)
  • 2020-12-16 16:39

    C++ has stricter rules than C regarding enums. You'll need to cast the value to the enumeration type when calling:

    do_something((CEnumType)(C_ENUM_VALUE_APPLE | C_ENUM_VALUE_BANANA));
    

    Alternatively, you can writer a wrapper function that takes an int to do the cast for you, if you want to avoid writing the cast every time you call it:

    void do_something_wrapper(int types)
    {
        do_something((CEnumType)types);
    }
    ...
    do_something_wrapper(C_ENUM_VALUE_APPLE | C_ENUM_VALUE_BANANA);
    

    Though I don't know if I want to see what you get when you cross an apple with a banana...

    0 讨论(0)
  • 2020-12-16 16:44

    You need to cast ints to enums in C++, but you can hide the cast in a custom OR operator:

    CEnumType operator|(CEnumType lhs, CEnumType rhs) {
        return (CEnumType) ((int)lhs| (int)rhs);
    }
    

    With this operator in place, you can write your original

    do_something(C_ENUM_VALUE_APPLE | C_ENUM_VALUE_BANANA);
    

    and it will compile and run without a problem.

    0 讨论(0)
  • 2020-12-16 16:45

    CEnumType A;

    A = (CEnumType)(A | C_ENUM_VALUE_APPLE);

    You can use it this way too.

    0 讨论(0)
提交回复
热议问题