问题听起来很痛苦。 假设你有枚举:
enum MyEnum {first, second, third};
现在我想将一些int转换为MyEnum。天真的方法
int i = 2;
MyEnum e = (MyEnum)i;
似乎没问题,但事实并非如此。首先,2将转换为'第三个'而不是第二个'正如人们所料。其次,这种转变是愚蠢的,我想要一个聪明的。 动机如下:
void foo(MyEnum e) { ... }
...
foo(2);
那个foo()应该总是收到第二个'无论这个枚举的实际价值是多少。 有两个明显的解决方案:
第一种解决方案显然很糟糕。不想写foo(convetIntToMyEnum(2));
我想写foo(2),编译器会自动调用我的转换函数。所以我需要的第二个解决方案。如果' int'是我自己的类,然后重载演员操作是微不足道的。但是' int'是内在类型。
我依稀记得有可能,但无法找到它。欣赏我的金发时刻的治疗方法。
答案 0 :(得分:3)
您不能为枚举重载“转换运算符”(通常这是“转换构造函数”或“用户定义的转换运算符”),因为它不是类,因此不能具有成员函数或构造函数。
你可能想要这样的东西:
class my_enum
{
public:
enum MyEnum {first=0x1000, second=0x2000, third=...};
private:
MyEnum m_value;
public:
my_enum(int _value) {
switch (_value) {
case 1: m_value = first; break;
case 2: m_value = second; break;
case 3: m_value = third; break;
default: throw std::invalid_argument("invalid value");
}
}
operator int() const {
switch (m_value) {
case first: return 1;
case second: return 2;
case third: return 3;
default: return 0;
}
}
};
void foo(my_enum e)
{
...
}
您可以定义所需的int
到enum value
之间的映射,只要它是可逆的。因为构造函数和强制转换操作符不是显式的,所以这将允许您想要的隐式转换。
答案 1 :(得分:0)
有第三个显而易见的解决方案:不要使用整数作为函数的参数,而是直接使用你的枚举。当你在它的时候,就把它变成一个枚举类吧!额外奖励:增加代码清晰度。这真的没有理由开始为糟糕的函数原型编写各种意外的转换。
如果从外部API为您提供了这些功能,那么请以正确的方式将它们包装起来。如果您需要枚举成员的原始整数值,那么只需调用显式转换函数即可。但是,当访问硬件本身时应该是它的声音,所以这些呼叫站点也可以被包装,你可以在上面的所有层中自由地做正确的事情。