在 C++ 中将 int 转换为 enum 的通用方法
在C++
中是否有将int
转换为enum
的通用方法?
Is there a generic way to cast int
to enum
in C++
?
如果 int
落在 enum
的范围内,它应该返回一个 enum
值,否则抛出一个 exception
.有没有办法通用编写它?应该支持多个 enum type
.
If int
falls in range of an enum
it should return an enum
value, otherwise throw an exception
. Is there a way to write it generically? More than one enum type
should be supported.
背景:我有一个外部enum 类型并且无法控制 源代码.我想将此值存储在数据库中并检索它.
Background: I have an external enum type and no control over the source code. I'd like to store this value in a database and retrieve it.
推荐答案
显而易见的事情是注释你的枚举:
The obvious thing is to annotate your enum:
// 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);
}
您需要使用 e
使数组保持最新,如果您不是 e
的作者,这会很麻烦.正如 Sjoerd 所说,它可能可以通过任何体面的构建系统实现自动化.
You need the array to be kept up to date with e
, which is a nuisance if you're not the author of e
. As Sjoerd says, it can probably be automated with any decent build system.
无论如何,您都面临 7.2/6:
In any case, you're up against 7.2/6:
对于枚举,其中 emin 是最小的枚举数和 emax 是最大,枚举值是基础类型的值在 bmin 到 bmax 的范围内,其中 bmin和 bmax 分别是的最小值和最大值可以存储 emin 的最小位域和 emax.可以定义一个枚举值不由其任何枚举??器定义.
For an enumeration where emin is the smallest enumerator and emax is the largest, the values of the enumeration are the values of the underlying type in the range bmin to bmax, where bmin and bmax are, respectively, the smallest and largest values of the smallest bit-field that can store emin and emax. It is possible to define an enumeration that has values not defined by any of its enumerators.
因此,如果您不是 e
的作者,您可能会也可能不会保证 e
的有效值实际出现在其定义中.
So if you aren't the author of e
, you may or may not have a guarantee that valid values of e
actually appear in its definition.
相关文章