简体   繁体   English

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

[英]Using C flag enums in C++

I have a C API that defines an enum like so: 我有一个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;

There is a method that uses the enum, defined as: 有一种使用枚举的方法,定义如下:

void do_something(CEnumType types);

In C, you can call something like: 在C中,您可以调用以下内容:

do_something(C_ENUM_VALUE_APPLE | C_ENUM_VALUE_BANANA);

However, if you try to call it this way in C++ (Linux, g++ compiler), you get an error, invalid conversion from 'int' to 'CEnumType' . 但是,如果您尝试在C ++(Linux,g ++编译器)中以这种方式调用它,则会出现错误, 从“int”到“CEnumType”的无效转换

What is the correct way to use this C API from my C++ application? 从我的C ++应用程序中使用此C API的正确方法是什么?

You need to cast int s to enums in C++, but you can hide the cast in a custom OR operator: 您需要在C ++中将int为枚举,但您可以在自定义OR运算符中隐藏转换:

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. 它将编译并运行没有问题。

C++ has stricter rules than C regarding enums. 对于枚举,C ++有比C更严格的规则。 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: 或者,你可以编写一个包装器函数,它接受一个int来为你做演员表,如果你想避免每次调用它时都要编写演员:

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... 虽然我不知道当你用香蕉过苹果时我是否想看看你得到了什么......

In the case of bitwise operations, the expression evaluates to a primitive type, ie int , long , etc. However, your function takes a non-primitive type ( CEnumType ). 在按位运算的情况下,表达式求值为基本类型,即intlong等。但是,您的函数采用非基本类型( 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));

CEnumType A; CEnumType A;

A = (CEnumType)(A | C_ENUM_VALUE_APPLE); A =(CEnumType)(A | C_ENUM_VALUE_APPLE);

You can use it this way too. 你也可以这样使用它。

By or-ing two enum values, you're creating an invalid value (0x3 is not in enum CEnumType). 通过输入两个枚举值,您将创建一个无效值(0x3不在枚举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));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM