简体   繁体   English

如何将C bitflag枚举转换为C ++?

[英]How should C bitflag enumerations be translated into C++?

C++ is mostly a superset of C, but not always. C ++主要是C的超集,但并非总是如此。 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. 特别是,虽然C和C ++中的枚举值都隐式转换为int,但反之则不然:只有在C中,int会转换回枚举值。 Thus, bitflags defined via enumeration declarations don't work correctly. 因此,通过枚举声明定义的bitflags无法正常工作。 Hence, this is OK in C, but not in C++: 因此,这在C中是可以的,但在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.)? 如何有效和正确地处理这个问题,理想情况下不会损害使用Foo作为变量类型的调试器友好性质(它会分解为手表中的组件位标志等)?

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. 澄清:我正在将一个大型(> 300K)C程序翻译成C ++,所以我在运行时和开发人员时间都在寻找有效的翻译。 Simply inserting casts in all the appropriate locations could take weeks. 只需在所有适当位置插入演员阵容可能需要数周时间。

Why not just cast the result back to a Foo? 为什么不把结果反馈给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: 获取2个Foo参数并返回Foo的运算符:

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

The int casts are there to prevent undesired recursion. int转换是为了防止不希望的递归。

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. 这听起来像是演员的理想应用程序 - 由你来告诉编译器是的,你的意思是用随机整数实例化一个Foo。

Of course, technically speaking, Foo_First | 当然,从技术上讲,Foo_First | Foo_Second isn't a valid value for a Foo. Foo_Second不是Foo的有效值。

将结果保留为int或static_cast:

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

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

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