在C++中将int转换为枚举的通用方法

Leo*_*nid 79 c++ enums casting

有没有投一个通用的方法int,以enumC++

如果int落在一个范围内enum它应该返回一个enum值,否则抛出一个exception.有没有办法一般地写它?不止一个enum type应予以支持.

背景:我有一个外部枚举类型,无法控制源代码.我想将此值存储在数据库中并检索它.

Ste*_*sop 37

显而易见的是注释你的枚举:

// generic code
#include <algorithm>

template <typename T>
struct enum_traits {};

template<typename T, size_t N>
T *endof(T (&ra)[N]) {
    return ra + N;
}

template<typename T, typename ValType>
T check(ValType v) {
    typedef enum_traits<T> traits;
    const T *first = traits::enumerators;
    const T *last = endof(traits::enumerators);
    if (traits::sorted) { // probably premature optimization
        if (std::binary_search(first, last, v)) return T(v);
    } else if (std::find(first, last, v) != last) {
        return T(v);
    }
    throw "exception";
}

// "enhanced" definition of enum
enum e {
    x = 1,
    y = 4,
    z = 10,
};

template<>
struct enum_traits<e> {
    static const e enumerators[];
    static const bool sorted = true;
};
// must appear in only one TU,
// so if the above is in a header then it will need the array size
const e enum_traits<e>::enumerators[] = {x, y, z};

// usage
int main() {
    e good = check<e>(1);
    e bad = check<e>(2);
}
Run Code Online (Sandbox Code Playgroud)

你需要让数组保持最新状态e,如果你不是作者的话,那就太麻烦了e.正如Sjoerd所说,它可以通过任何体面的构建系统实现自动化.

在任何情况下,你都面临7.2/6:

对于枚举,其中emin是最小的枚举数且emax是最大的,枚举的值是bmin到bmax范围内的基础类型的值,其中bmin和bmax分别是最小值和最小值的最小值.可以存储emin和emax的位字段.可以定义具有未由其任何枚举​​器定义的值的枚举.

因此,如果您不是作者e,您可能会或可能不会保证e其定义中实际出现有效值.


Joh*_*ing 20

丑陋.

enum MyEnum { one = 1, two = 2 };

MyEnum to_enum(int n)
{
  switch( n )
  {
    case 1 :  return one;
    case 2 : return two;
  }
  throw something();
}
Run Code Online (Sandbox Code Playgroud)

现在是真正的问题.你为什么需要这个?代码很难看,不易编写(*?)而且不易维护,也不容易合并到代码中.代码告诉你这是错的.为什么打架呢?

编辑:

或者,鉴于枚举是C++中的整数类型:

enum my_enum_val = static_cast<MyEnum>(my_int_val);
Run Code Online (Sandbox Code Playgroud)

但这甚至比上面更丑陋,更容易出错,并且不会按照你的意愿抛出.

  • 甲`的static_cast <MyEnum>`将工作,以及,应当优于`的reinterpret_cast <MyEnum>` (11认同)
  • @Leonid:据我所知,一般不能这样做.在某种程度上,你提出的任何解决方案都会为无效类型"抛出"(或做任何特殊的事情)必须有一个像我发布的那样的开关. (2认同)
  • -1为什么这个?这是正确的答案.仅仅因为它不是一些人所希望的答案并不意味着它是错误的. (2认同)