[英]Typedef a bitfield / mask in C++
我在C ++这样的问题:我可以的typedef位字段的值来自枚举?
代码将更具说明性:
typedef {
AUDIO = 0x01,
VIDEO = 0x02,
SUBTITLE = 0x04,
DATA = 0x08,
GUARD,
ALL = 0xFF
} my_enum_e;
// I'd like to replace 'unsigned int' by 'my_enum_e' or similar
int myFunction( unsigned int mask )
{
// code
}
// called like this:
myFunction( AUDIO|VIDEO|DATA );
在函数原型中,我想使用my_enum_e
作为输入值类型,这样在探索代码时,您可以立即知道应该放在哪里的值。
现在,将原型更改为
int myFunction( my_enum_e mask );
让编译器抱怨一个强制转换错误。 我无法通过强制转换函数调用来修复它:
int myFunction( my_enum_e mask )
{
// code
}
myFunction( (my_enum_e)(VIDEO|AUDIO|DATA) );
但我发现这非常可怕,我甚至不确定它是否合法(它能否截断值?)。
你有解决方案吗?
为|
添加显式重载 可能还有其他运营商。
my_enum_e operator|(my_enum_e a, my_enum_e b)
{ return my_enum_e(unsigned(a)|unsigned(b)); }
可以编写一个宏来定义给定位掩码类型的所有所需操作符。
#define BITMASK_OPERATORS(T) T operator|(T a, T b) { return T(unsigned(a)|unsigned(b)); } \
T operator^(T a, T b) ...
如何实现一个特殊的功能来处理这个问题:
template <typename Enum>
Enum bitField(unsigned bits) {
return static_cast<Enum>(bits);
}
它增加了你正在做的事情的表现力:
myFunction(bitField<my_enum_e>(VIDEO|AUDIO|DATA));
如果你想要更复杂,你可以这样做:
template <typename Enum>
struct BitField {
Enum value;
BitField(Enum value) : value(value) {}
BitField operator|(Enum more) {
return BitField(value | more);
}
BitField operator&(Enum more) {
return BitField(value & more);
}
BitField operator~() {
return BitField(~value);
}
operator Enum() {
return value;
}
}
这将允许你写
myFunction(BitField<my_enum_e>(VIDEO) | AUDIO | DATA);
当您执行按位运算时,编译器会将VIDEO | AUDIO | DATA视为整数值,因此您必须使用* my_enum_e *进行转换。
我建议您查看此主题: 您使用的C ++中哪个Typesafe枚举? - [Boost Vault]中提到的实现(文件名enum_rev4.6.zip
)。 1还提供了声明BOOST_BITFIELD
的可能性:
BOOST_BITFIELD(my_enum_e,
(AUDIO) (0x01)
(VIDEO) (0x02)
(SUBTITLE) (0x04)
(DATA) (0x08)
);
然后你可以声明你的功能:
int myFunction( const my_enum_e & in_enum )
{
if ( in_enum[AUDIO] ) ...
}
然后使用
void callerFunction()
{
my_enum_e mask;
mask.set(my_enum_e::AUDIO);
mask.set(my_enum_e::VIDEO | my_enum_e::SUBTITLE );
cout << mask << " = " << hex << mask.value() << endl; // will print: AUDIO|VIDEO|SUBTITLE = 0x7
myFunction( mask );
}
api的文档不是那么好。 但是这些软件包附带了一个显示几种用法的测试。
解决这个问题的一种方法是typedef int MY_FLAGS;
然后#define你的所有值: #define AUDIO 0x01
等。这样编译器不会呻吟,你仍然在函数调用中得到类型:
int myFunction( MY_FLAGS mask );
myFunction( VIDEO|AUDIO|DATA );
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.