Reputation: 17956
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 << 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:
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’.
What is the correct way to use this C API from my C++ application?
Upvotes: 13
Views: 3370
Reputation: 1150
CEnumType A;
A = (CEnumType)(A | C_ENUM_VALUE_APPLE);
You can use it this way too.
Upvotes: 1
Reputation: 727047
You need to cast int
s 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.
Upvotes: 23
Reputation: 4176
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));
Upvotes: 5
Reputation: 400642
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...
Upvotes: 6
Reputation: 8116
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));
Upvotes: 0