【问题标题】:How to cast enums?如何投射枚举?
【发布时间】:2017-01-07 22:21:31
【问题描述】:

我有一个第三方无范围枚举(我无法修改),我真的很想将其转换为我自己的范围枚举。我怎样才能提供类似转换运算符的东西?

我想做的是这样的:

#include <iostream>
enum ThirdPartyLetter {
  A=4,
  B=5
};

enum class MyNumber {
  ONE=1,
  TWO=2

  // This doesn't compile, of course
  /*Number(const ThirdPartyLetter& rhs) {
    if(rhs == ThirdPartyLetter::A) {
      return ONE;
    }
    else {
      return TWO;
    }
  }*/
};


int main() {
  ThirdPartyLetter letter = ThirdPartyLetter::A;
  MyNumber number = static_cast<MyNumber>(letter);
  // Without the cast, this prints 4 (an invalid enum value!)
  std::cout << int(number) << std::endl;
}

有没有办法提供从ThirdPartyNumberMyNumber 的某种类型转换?

【问题讨论】:

  • 您对演员阵容的期望是什么?
  • 好吧,我希望演员将 ThirdPartyLetter::A 转换为 MyNumber::ONE,并将 ThirdPartyLetter::B 转换为 MyNumber::TWO。所以我的预期输出是 1。

标签: c++ c++11 enums casting


【解决方案1】:

在 C++ 的编译时,一种惯用的方法是使用特征。
举个例子:

enum Foo { ONE, TWO };
enum Bar { THREE, FOUR };

template<Foo> struct conv;
template<> struct conv<Foo::ONE> { static constexpr Bar value = Bar::THREE; };
template<> struct conv<Foo::TWO> { static constexpr Bar value = Bar::FOUR; };

如果您想在运行时执行此操作,也许开关非常适合。
无论如何,您仍然可以使用特征来集中您的转换逻辑并执行以下操作:

Bar get(Foo choice) {
    switch(choice) {
    case Foo::ONE:
        return conv<ONE>::value;
     case Foo::TWO:
        return conv<TWO>::value;
    }
}

【讨论】:

  • 为什么使用特质比仅仅使用case Foo::ONE: return Bar::THREE更好?
  • @ThomasJohnson 通常,如果您有多个使用这些枚举的点,则转换逻辑中的每次更改都需要您修改所有这些代码。在这种情况下,特征就像一个集中定义,您可以在其上编写代码。
  • 谢谢,有道理
  • 为什么使用带有内部值的结构而不是模板变量?
  • 这是另一种解决方案。您可以使用它发布答案。
猜你喜欢
  • 2011-10-05
  • 1970-01-01
  • 2018-01-27
  • 1970-01-01
  • 1970-01-01
  • 2019-08-14
  • 1970-01-01
  • 2018-04-11
  • 2016-09-08
相关资源
最近更新 更多