How should C bitflag enumerations be translated into C++?

浪尽此生 提交于 2019-12-19 09:47:04

问题


C++ is mostly a superset of C, but not always. In particular, while enumeration values in both C and C++ implicitly convert into int, the reverse isn't true: only in C do ints convert back into enumeration values. Thus, bitflags defined via enumeration declarations don't work correctly. Hence, this is OK in C, but not in C++:

typedef enum Foo
{
    Foo_First = 1<<0,
    Foo_Second = 1<<1,
} Foo;

int main(void)
{
    Foo x = Foo_First | Foo_Second; // error in C++
    return 0;
}

How should this problem be handled efficiently and correctly, ideally without harming the debugger-friendly nature of using Foo as the variable type (it decomposes into the component bitflags in watches etc.)?

Consider also that there may be hundreds of such flag enumerations, and many thousands of use-points. Ideally some kind of efficient operator overloading would do the trick, but it really ought to be efficient; the application I have in mind is compute-bound and has a reputation of being fast.

Clarification: I'm translating a large (>300K) C program into C++, so I'm looking for an efficient translation in both run-time and developer-time. Simply inserting casts in all the appropriate locations could take weeks.


回答1:


Why not just cast the result back to a Foo?

Foo x = Foo(Foo_First | Foo_Second);

EDIT: I didn't understand the scope of your problem when I first answered this question. The above will work for doing a few spot fixes. For what you want to do, you will need to define a | operator that takes 2 Foo arguments and returns a Foo:

Foo operator|(Foo a, Foo b)
{
    return Foo(int(a) | int(b));
}

The int casts are there to prevent undesired recursion.




回答2:


It sounds like an ideal application for a cast - it's up to you to tell the compiler that yes, you DO mean to instantiate a Foo with a random integer.

Of course, technically speaking, Foo_First | Foo_Second isn't a valid value for a Foo.




回答3:


Either leave the result as an int or static_cast:

Foo x = static_cast<Foo>(Foo_First | Foo_Second); // not an error in C++


来源:https://stackoverflow.com/questions/199606/how-should-c-bitflag-enumerations-be-translated-into-c

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!