【发布时间】:2013-03-31 03:26:59
【问题描述】:
如何在强类型(作用域)enum(在 C++11、GCC 中)上重载 |= 运算符?
我想测试、设置和清除强类型枚举的位。为什么要强类型?因为我的书说这是很好的做法。但这意味着我必须在任何地方static_cast<int>。为了防止这种情况,我重载了| 和& 运算符,但我不知道如何在枚举上重载|= 运算符。对于一个类,您只需输入 the operator definition in the class,但对于在语法上似乎不起作用的枚举。
这是我目前所拥有的:
enum class NumericType
{
None = 0,
PadWithZero = 0x01,
NegativeSign = 0x02,
PositiveSign = 0x04,
SpacePrefix = 0x08
};
inline NumericType operator |(NumericType a, NumericType b)
{
return static_cast<NumericType>(static_cast<int>(a) | static_cast<int>(b));
}
inline NumericType operator &(NumericType a, NumericType b)
{
return static_cast<NumericType>(static_cast<int>(a) & static_cast<int>(b));
}
我这样做的原因:这就是它在强类型 C# 中的工作方式:一个枚举只有一个结构,其基础类型的字段,以及在其上定义的一堆常量。但它可以有任何适合枚举隐藏字段的整数值。
而且似乎 C++ 枚举的工作方式完全相同。在这两种语言中,强制转换都需要从 enum 到 int,反之亦然。但是,在 C# 中,位运算符默认是重载的,而在 C++ 中则不是。
【问题讨论】:
-
我不确定这是否有意义。单个位被枚举,但
PadWithZero | NegativeSign = 0x03不是一个有效的枚举常量。 -
@Useless 是的,这只是一个基于 Linux 0.1 中用于实现
printf的 NUMERICTYPE_ 定义序列的 C++11 版本的示例。结果必须是原始枚举的成员吗?我来自 C# 背景,期望作用域枚举的行为类似于 C# 中的枚举。 -
我是说您的枚举类型在
|下没有关闭,因此将其强制为该类型的(非法值)是没有意义的。枚举标志常量值,但让标志组合为int。 -
@Useless - 该值不非法。任何适合位的值都可以。那种位掩码一直都是做的,没毛病。
-
我会说 NumericType 的组合是一个集合,它是与 NumericType 不同的类型。你为什么不创建一个 NumericTypeSet 类或其他东西?从语义上讲,这可能更有意义。
标签: c++ c++11 enums operator-overloading bitwise-operators