枚举int操作符或函数 [英] enum-int casting: operator or function

查看:148
本文介绍了枚举int操作符或函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

 枚举En {VALUE_A,VALUE_B,VALUE_C} 

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

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

很多时候,我有一个int X等于ValA或ValB或ValC,我必须把它转换为En的相应值(ValA到VALUE_A, ValB到VALUEB等),因为一些函数签名具有枚举En。很多时候,我要做相反的操作,将枚举En转换为ValA或ValB或ValC。我不能改变这些功能的签名,并且有很多这样的功能。



问题是:如何做翻译?我应该创建2个转换运算符,这将被隐式使用?或者我应该只有2个翻译功能,将明确使用:

  En ToEn(int)
int FromEn En)

还是任何其他解决方案?

解决方案

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

  template< typename T> 
T my_enum_convert(int);

模板<>
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;
//没有默认值,所以如果我们忘记了一个case GCC会警告我们
}
}

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

或者类似的东西 - 如果在使用时出现问题,可以调整。 p>

我不会使用隐式转换的原因是,已经有是从En到int的隐式转换,它给出了错误的答案。即使你可以用可以替换的东西给出正确的答案,结果代码看起来不会像做任何转换。这将阻止任何后来看代码而不是键入一个转换例程的调用将阻碍你。



如果你想转换为int并从int转换看起来很不一样,那么你可以给模板和函数上面不同的名字。



或者,如果你想让它们看起来一样(更像static_cast)您可以:

 模板< 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< T(ValA);,如果你认为单参数构造函数是C风格的转换,因此是不允许的)。


In the external code that I am using there is enum:

enum En {VALUE_A, VALUE_B, VALUE_C};

In another external code that I am using there are 3 #define directives:

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

Many times I have int X which is equal to ValA or ValB or ValC, and I have to cast it to the corresponding value of En (ValA to VALUE_A, ValB to VALUEB, etc) because some function signature has enum En. And many times I have to do the opposite operation, translate enum En to ValA or ValB or ValC. I cannot change the signatures of these functions, and there are many such functions.

The question is: How to do the translation? Should I create 2 cast operators, which will be used implicitly? Or should I just have 2 translation functions which will be used explicitly:

En ToEn(int)
int FromEn(En)

Or any other solution?

解决方案

Since you can't just cast here, I would use a free function, and if there are likely to be other enums that also need converting, try to make it look a little bit like the builtin casts:

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

Or something like that - might adjust it if issues arise while using it.

The reason I wouldn't use implicit conversion is that there already is an implicit conversion from En to int, which gives the wrong answer. Even if you can reliably replace that with something which gives the right answer, the resulting code won't look as though it's doing any conversion. IMO this will hinder anyone who later looks at the code more than typing a call to a conversion routine will hinder you.

If you want converting to int and converting from int to look very different, then you could give the template and the function above different names.

Alternatively, if you want them to look the same (and more like a static_cast), you could do:

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);

As written, T must have an implicit conversion from int. If you want to support T that only has an explicit conversion, use "return T(ValA);" instead (or "return static_cast<T>(ValA);", if you consider that single-arg constructors are C-style casts and hence impermissible).

这篇关于枚举int操作符或函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆