【发布时间】:2016-06-25 15:45:51
【问题描述】:
我使用这样的函数将 int(来自旧版 API)转换为 enum:
TestEnum to_test_enum(int value) {
TestEnum converted(static_cast<TestEnum>(value));
# pragma GCC diagnostic push
# pragma GCC diagnostic error "-Wswitch"
switch (converted) {
case TestEnum::A:
case TestEnum::B:
return converted;
}
# pragma GCC diagnostic pop
throw std::runtime_error("wrong value");
}
to_test_enum 如果向to_enum 传递了无效值,则抛出异常,否则返回相应的TestEnum 值。 pragma 确保在缺少合法值的情况下会出现编译器错误。
像这样的行现在将转换一个整数并在运行时进行有效性检查:
enum class TestEnum {
A = 1,
B = 2,
};
auto v1 = to_test_enum(2);
auto v2 = to_test_enum(3); // will throw
问题:我想知道是否可以通过某种模板魔法将其变成函数模板:
template<class E>
E to_enum(int value) {
E converted(static_cast<E>(value));
switch (converted) {
EACH ELEMENT e IN E: case e: <--- here goes some unrolling magic
return converted;
}
throw std::runtime_error("wrong value");
}
然后将像这样使用该函数:
auto v1 = to_enum<TestEnum>(2);
auto v2 = to_enum<TestEnum>(3); // will throw
【问题讨论】:
-
不,(除非你做了一些诡计的事情来通过一些自省来声明枚举)。
-
如果您添加 First 和 Last 或其他占位符元素来表示可能的范围,那么这可能是可能的,但是这会强制枚举值覆盖连续的值范围而没有任何漏洞,不确定如果你想这样做。
-
我发现了一些有用的预处理器魔法,它可以从同一个文本文件创建几个相关的 C++ 事物(例如,创建一个映射 enum -> enumNameString,定义 enumType_first 和 enumType_last,并可能定义一个内联转换函数)。
-
This answer (免责声明:作者)描述了一些你可以做的声明技巧来实现这一点。它没有显示
from_int函数,但希望一旦您可以进行声明,就可以清楚地了解如何实现它。需要注意的一点是,您可以实现的明显转换需要与枚举数成线性关系的时间。
标签: c++ templates enums casting int