在C++中使用C标志枚举

Dav*_*eer 11 c c++ enums

我有一个C API,定义了这样的枚举:

typedef enum
{
  C_ENUM_VALUE_NONE    = 0,
  C_ENUM_VALUE_APPLE   = (1 << 0),
  C_ENUM_VALUE_BANANA  = (1 << 1),
  C_ENUM_VALUE_COCONUT = (1 << 2),
  // etc.
  C_ENUM_VALUE_ANY     = ~0
} CEnumType;
Run Code Online (Sandbox Code Playgroud)

有一种使用枚举的方法,定义如下:

void do_something(CEnumType types);
Run Code Online (Sandbox Code Playgroud)

在C中,您可以调用以下内容:

do_something(C_ENUM_VALUE_APPLE | C_ENUM_VALUE_BANANA);
Run Code Online (Sandbox Code Playgroud)

但是,如果您尝试在C++(Linux,g ++编译器)中以这种方式调用它,则会出现错误,从"int"到"CEnumType"的无效转换.

从我的C++应用程序中使用此C API的正确方法是什么?

das*_*ght 22

您需要使用intC++将枚举强制转换为枚举,但您可以在自定义OR运算符中隐藏强制转换:

CEnumType operator|(CEnumType lhs, CEnumType rhs) {
    return (CEnumType) ((int)lhs| (int)rhs);
}
Run Code Online (Sandbox Code Playgroud)

有了这个操作符,您就可以编写原始文件了

do_something(C_ENUM_VALUE_APPLE | C_ENUM_VALUE_BANANA);
Run Code Online (Sandbox Code Playgroud)

它将编译并运行没有问题.

  • 为了重载`|`运算符的聪明才智+1! (3认同)
  • 它有一个很好的定义行为,有一个枚举类型的对象,其值不是指定的枚举值之一? (2认同)

Ada*_*eld 6

对于枚举,C++有比C更严格的规则.调用时,您需要将值强制转换为枚举类型:

do_something((CEnumType)(C_ENUM_VALUE_APPLE | C_ENUM_VALUE_BANANA));
Run Code Online (Sandbox Code Playgroud)

或者,你可以int编写一个包装器函数来为你做一个演员,如果你想避免每次调用它时都要编写演员:

void do_something_wrapper(int types)
{
    do_something((CEnumType)types);
}
...
do_something_wrapper(C_ENUM_VALUE_APPLE | C_ENUM_VALUE_BANANA);
Run Code Online (Sandbox Code Playgroud)

虽然我不知道当你用香蕉过苹果时我是否想看看你得到了什么......


ins*_*r-g 5

在按位操作的情况下,该表达式的基本类型,即int,long等等.然而,你的函数采用一个非原始型(CEnumType).我知道绕过这个的唯一方法是转换表达式.例如:

do_something((CEnumType) (C_ENUM_VALUE_APPLE | C_ENUM_VALUE_BANANA));
Run Code Online (Sandbox Code Playgroud)