c++ - 枚举整数类型转换 : operator or function

标签 c++ enums casting

在我使用的外部代码中有枚举:

enum En {VALUE_A, VALUE_B, VALUE_C};

在我使用的另一个外部代码中有 3 个#define 指令:

#define ValA 5
#define ValB 6
#define ValC 7

很多时候我有等于 ValA 或 ValB 或 ValC 的 int X,我必须将它转换为 En 的相应值(ValA 到 VALUE_A,ValB 到 VALUEB,等等),因为某些函数签名具有枚举 En。而很多时候我不得不做相反的操作,将 enum En 翻译成 ValA 或 ValB 或 ValC。我无法更改这些函数的签名,而且有很多这样的函数。

问题是:翻译怎么做?我应该创建 2 个将被隐式使用的转换运算符吗?或者我应该只有 2 个将被显式使用的翻译功能:

En ToEn(int)
int FromEn(En)

或者任何其他解决方案?

最佳答案

因为你不能只在这里转换,我会使用一个自由函数,如果可能还有其他枚举也需要转换,试着让它看起来有点像内置转换:

template<typename T>
T my_enum_convert(int);

template<>
En my_enum_convert<En>(int in) {
    switch(in) {
        case ValA: return VALUE_A;
        case ValB: return VALUE_B;
        case ValC: return VALUE_C;
        default: throw std::logic_error(__FILE__ ": enum En out of range");
    }
}

int my_enum_convert(En in) {
    switch(in) {
        case VALUE_A: return ValA;
        case VALUE_B: return ValB;
        case VALUE_C: return ValC;
        // no default, so that GCC will warn us if we've forgotten a case
    }
}

En enumValue = my_enum_convert<En>(ValA);
int hashDefineValue = my_enum_convert(VALUE_A);
enumValue = my_enum_convert<En>(0); // throws exception

或类似的东西 - 如果在使用它时出现问题,可能会对其进行调整。

我不使用隐式转换的原因是已经存在从 En 到 int 的隐式转换,这给出了错误的答案。即使您可以用给出正确答案的东西可靠地替换它,生成的代码看起来也不会像在进行任何转换。在我看来,这比键入对转换例程的调用更会阻碍以后查看代码的任何人。

如果你想转换为 int 和从 int 转换看起来非常不同,那么你可以给模板和函数上面不同的名称。

或者,如果您希望它们看起来相同(并且更像 static_cast),您可以这样做:

template<typename T>
T my_enum_convert(En in) {
    switch(in) {
        case VALUE_A: return ValA;
        case VALUE_B: return ValB;
        case VALUE_C: return ValC;
    }
}

int hashDefineValue = my_enum_convert<int>(VALUE_A);

如所写,T 必须从 int 进行隐式转换。如果要支持只有显式转换的 T,请使用“return T(ValA);”相反(或“return static_cast(ValA);”,如果你认为单参数构造函数是 C 风格的转换,因此是不允许的)。

关于c++ - 枚举整数类型转换 : operator or function,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/367819/

相关文章:

c++ - 两行C++代码的问题

c++ - 将 "pass"函数模板作为通用可变参数 lambda 返回语句的好方法吗?

enums - 如何迭代枚举,并转换 obj

c# - 创建枚举后销毁 EnumBuilder?

java - 使用 Realm 支持枚举?

c# - 为什么我应该用 "unchecked"明确包围?

c++ - 如何使用dynamic_cast

python - numpy - 获取随机整数作为 float

c++ - GCC 对 lambda 中的静态变量做了什么?

c++ - GLM 在声明后定义一个 vec3