【问题标题】:Overload cast operator between two enums两个枚举之间的重载强制转换运算符
【发布时间】:2011-09-05 18:14:20
【问题描述】:

有没有办法重载强制转换运算符以在两个枚举之间进行转换?

在我的代码中

enum devStatus
{
    NOT_OPERATING,
    INITIALISING,
    DEGRADED,
    NORMAL
};

enum dataStatus
{
    UNAVAILABLE = 1,
    DEGRADED,
    NORMAL
}

其中 NOT_OPERATING 和 INITIALISING 映射到 UNAVAILABLE; DEGRADED 和 NORMAL 映射直接穿过。这些由外部接口修复。

我正在寻找一种在 devStatusdataStatus 之间进行转换的方法,并且希望能够编写如下内容:

devStatus devSts;
getDeviceStatus(&devSts);
dataStatus dataSts = (dataStatus)devSts;

我知道如果这些是类,我可以写 devStatus::operator dataStatus() 来做到这一点。有没有办法为枚举做到这一点?

我可以有一个免费的功能 dataStatus devStatus2dataStatus(const devStatus& desSts)

【问题讨论】:

    标签: c++ casting enums


    【解决方案1】:

    在 C++ 中,转换运算符只能在类、结构和联合声明中声明。它们不能在类型之外声明(例如 operator+)。枚举类型声明不支持实例成员,因此您需要使用转换函数。这样做也会使调用代码更清晰。以下示例演示了这一点,使用自定义命名空间来确定枚举和转换函数的范围:

    namespace TheirEnum {
       enum Type {
          Value1,
          Value2
       };
    }
    namespace MyEnum {
       enum Type {
          Value1,
          Value2
       };
    
       TheirEnum::Type ToTheirEnum (Type e) {
          switch (e) {
             case Value1: return TheirEnum::Value1;
             case Value2: return TheirEnum::Value2;
             default: throw std::invalid_argument("e");
          }
       }
    }
    
    // usage:
    TheirEnum::Type e = MyEnum::ToTheirEnum(MyEnum::Value1);
    

    【讨论】:

    • 为每个枚举定义一个类和转换运算符的优点/缺点是什么?不利的一面是更多样板代码。从好的方面来说,没有转换函数在外部命名空间周围浮动 - 尽管已经说过枚举已经在那里浮动。效率应该与编译器优化相同。
    • 我同意 C++ 枚举的名称范围并不理想,但可以通过使用命名空间包装枚举声明和转换函数来轻松避免它,而不必走下创建一个兔子洞每个枚举的类。沿着这条路走下去会带来逻辑问题,例如 is-a/has-a 关系以及应该/必须为该类型提供哪些运算符。我认为这样做对于大多数枚举来说可能是矫枉过正。
    • 我用示例命名空间声明和示例用法更新了答案。
    猜你喜欢
    • 1970-01-01
    • 2011-02-04
    • 1970-01-01
    • 2011-11-18
    • 2017-06-19
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    相关资源
    最近更新 更多