如何在scoped enum上重载| =运算符?

Dan*_*ker 29 c++ enums operator-overloading bitwise-operators c++11

如何|=在强类型(作用域)enum(在C++ 11,GCC中)重载操作符

我想在强类型枚举上测试,设置和清除位.为何选择强类型?因为我的书说这是好习惯.但这意味着我必须static_cast<int>到处都是.为了防止这种情况,我重载了|&运算符,但我无法弄清楚如何在枚举上重载|=运算符.对于一个类,您只需将运算符定义放在类中,但对于在语法上似乎不起作用的枚举.

这是我到目前为止:

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));
}
Run Code Online (Sandbox Code Playgroud)

我这样做的原因:这是它在强类型C#中的工作方式:一个枚举只有一个结构,其中包含一个基础类型的字段,并在其上定义了一堆常量.但它可以包含任何适合枚举隐藏字段的整数值.

似乎C++枚举的工作方式完全相同.在两种语言中,强制转换都需要从枚举变为int,反之亦然.但是,在C#中,默认情况下,按位运算符会重载,而在C++中,它们不会重载.

qPC*_*vir 31

inline NumericType& operator |=(NumericType& a, NumericType b)
{
    return a= a |b;
}
Run Code Online (Sandbox Code Playgroud)

这有效吗?编译并运行:( Ideone)

#include <iostream>
using namespace std;

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));
}

inline NumericType& operator |=(NumericType& a, NumericType b)
{
    return a= a |b;
}

int main() {
    // your code goes here
    NumericType a=NumericType::PadWithZero;
    a|=NumericType::NegativeSign;
    cout << static_cast<int>(a) ;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

打印3.

  • 如果枚举是在类内部定义的,并且还想在该类内部声明运算符,则将它们声明为“ friend”,否则编译器会抱怨该运算符有太多参数-然后认为它们适用于类而不是枚举。或在类之外声明运算符,但随后必须用类名来限定枚举名称。如果在类C内定义了枚举E,则操作符| 因为该枚举应在类外部声明为“内联C :: E运算符|(C :: E a,C :: E b)”,或在类内部声明为“朋友E运算符|(E a,E b)” 。 (4认同)