应该如何将C位标志枚举转换为C++

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

本文关键字:枚举 标志 转换 C++      更新时间:2023-10-16

C++主要是C的超集,但并不总是。特别是,虽然C和C++中的枚举值都隐式转换为int,但事实并非如此:只有在C中,int才会转换回枚举值。因此,通过枚举声明定义的位标志不能正常工作。因此,这在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;
}

应该如何有效、正确地处理这个问题,最好是在不损害使用Foo作为变量类型(它分解为手表等中的组件位标志)的调试器友好性的情况下?

还要考虑可能有数百个这样的标志枚举,以及数千个使用点。理想情况下,某种高效的运算符重载会起到作用,但它确实应该是高效的;我心目中的应用程序是受计算限制的,以速度快著称。

澄清:我正在将一个大型(>300K)C程序翻译成C++,所以我正在寻找一个在运行时和开发人员时间都有效的翻译。简单地在所有合适的位置插入石膏可能需要数周时间。

为什么不将结果强制转换回Foo?

Foo x = Foo(Foo_First | Foo_Second);

编辑:当我第一次回答这个问题时,我不明白你问题的范围。以上内容将适用于进行一些局部修复。对于您想要做的事情,您需要定义一个|运算符,它接受2个Foo参数并返回一个Foo:

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

int强制转换是为了防止不需要的递归。

这听起来像是一个理想的强制转换应用程序——这取决于你告诉编译器,是的,你的意思是用随机整数实例化Foo。

当然,从技术上讲,Foo_First|Foo_Second不是Foo的有效值。

将结果保留为int或static_cast:

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