与实施枚举的类的交换机/案例语句的问题(要派生)
在网上进行了一些搜索之后,我至少发现了C ++ 14枚举的解决方案,正如您在下面的代码中看到的那样,仅提及了基类。除了发生汇编误差的开关/情况使用外,一切都很好。
有人还可以对肌部类提出简单的修改,以便在开关/案例语句中使用?
非常感谢。
#include <iostream>
#include <cstdint>
class MyEnum
{
public:
static const MyEnum VAL_1;
static const MyEnum VAL_2;
static const MyEnum VAL_3;
MyEnum() {}
explicit MyEnum(uint8_t val) : value(val) {}
virtual ~MyEnum() {}
bool operator<(const MyEnum& other) const { return value < other.value; }
bool operator==(const MyEnum& other) const { return value == other.value; }
bool operator!=(const MyEnum& other) const { return !(operator==(other)); }
operator uint8_t() const { return value; }
protected:
static const uint8_t Val1 = 1;
static const uint8_t Val2 = 2;
static const uint8_t Val3 = 3;
uint8_t value;
};
const MyEnum MyEnum::VAL_1(Val1);
const MyEnum MyEnum::VAL_2(Val2);
const MyEnum MyEnum::VAL_3(Val3);
int main()
{
MyEnum e;
e = MyEnum::VAL_1;
if (e == MyEnum::VAL_1)
std::cout << "Compiles" << std::endl;
switch (e)
{
case MyEnum::VAL_1:
{
std::cout << "Doesn't compile" << std::endl;
}
}
exit(0);
}
如我在第一篇文章中所述,感谢您的所有答案,我的问题主要是在C ++枚举继承上,然后在下面找到更新的示例。
目前,我有两个问题:
第一个肌肌层类实现停止工作启用toString()方法,只需使用-dto_string编译,您可以看到对E值的影响。我知道我正在尝试做一些丑陋的事情,有没有正确的方法可以实现相同的结果?
我使用将肌发育类型作为输入的函数有很多代码,我无法修改它。使用包装真实枚举的第二个建议的肌部实现,只需用-dmyenum_2编译,我就会出现错误,因为包装枚举类型(Vale)被期望为功能输入,而不是肌部本身。有什么想法吗?
再次感谢。
#include <iostream>
#include <cstdint>
#ifndef MYENUM_2
class MyEnum
{
public:
static const MyEnum VAL_1;
static const MyEnum VAL_2;
static const MyEnum VAL_3;
MyEnum() {}
constexpr explicit MyEnum(uint8_t val) : value(val) {}
bool operator<(const MyEnum& other) const { return value < other.value; }
bool operator==(const MyEnum& other) const { return value == other.value; }
bool operator!=(const MyEnum& other) const { return !(operator==(other)); }
constexpr operator uint8_t() const { return value; }
#ifdef TO_STRING
virtual std::string toString()
{
printf("value = %d\n", value);
if (value == Val1)
return "1";
else if (value == Val2)
return "2";
else if (value == Val3)
return "3";
}
#endif
protected:
static const uint8_t Val1 = 1;
static const uint8_t Val2 = 2;
static const uint8_t Val3 = 3;
uint8_t value;
};
constexpr MyEnum MyEnum::VAL_1(Val1);
constexpr MyEnum MyEnum::VAL_2(Val2);
constexpr MyEnum MyEnum::VAL_3(Val3);
class MyDerivedEnum : public MyEnum
{
public:
static const MyDerivedEnum VAL_4;
static const MyDerivedEnum VAL_5;
static const MyDerivedEnum VAL_6;
MyDerivedEnum() {}
constexpr explicit MyDerivedEnum(uint8_t val) : MyEnum(val) {}
#ifdef TO_STRING
std::string toString()
{
printf("value = %d\n", value);
if (value == Val4)
return "4";
else if (value == Val5)
return "5";
else if (value == Val6)
return "6";
}
#endif
private:
static const uint8_t Val4 = 4;
static const uint8_t Val5 = 5;
static const uint8_t Val6 = 6;
};
constexpr MyDerivedEnum MyDerivedEnum::VAL_4(Val4);
constexpr MyDerivedEnum MyDerivedEnum::VAL_5(Val5);
constexpr MyDerivedEnum MyDerivedEnum::VAL_6(Val6);
#else
class MyEnum
{
public:
typedef enum
{
VAL_1 = 1,
VAL_2,
VAL_3
} vale;
MyEnum() {}
explicit MyEnum(uint8_t val) : value((vale)val) {}
virtual ~MyEnum() {}
bool operator<(const MyEnum& other) const { return value < other.value; }
bool operator==(const MyEnum& other) const { return value == other.value; }
bool operator!=(const MyEnum& other) const { return !(operator==(other)); }
//replaced by operator vale :
//operator uint8_t() const { return value; }
MyEnum& operator = (const vale& v)
{
value = v;
return *this;
}
operator vale () const
{
return value;
}
//op ==, !=... to be written
protected:
vale value;
};
#endif
class A
{
public:
A() {}
~A() {}
void set(MyEnum e)
{
printf("e = %d\n", e);
}
};
#ifndef MYENUM_2
class B : A
{
public:
B() {}
~B() {}
void test(MyDerivedEnum e)
{
set(e);
}
};
#endif
int main()
{
A a;
#ifndef MYENUM_2
B b;
#endif
a.set(MyEnum::VAL_1);
#ifndef MYENUM_2
b.test(MyDerivedEnum::VAL_4);
#endif
exit(0);
}
after some searching on the Net, I found a satisfying, at least for me, solution for C++ 14 enums inheritance, as you can see in the code below, where only base class is mentioned. Everything works fine except for switch/case usage where a compilation error occurs.
May someone suggest a simple modification to MyEnum class in order to be used in switch/case statements, too?
Many thanks.
#include <iostream>
#include <cstdint>
class MyEnum
{
public:
static const MyEnum VAL_1;
static const MyEnum VAL_2;
static const MyEnum VAL_3;
MyEnum() {}
explicit MyEnum(uint8_t val) : value(val) {}
virtual ~MyEnum() {}
bool operator<(const MyEnum& other) const { return value < other.value; }
bool operator==(const MyEnum& other) const { return value == other.value; }
bool operator!=(const MyEnum& other) const { return !(operator==(other)); }
operator uint8_t() const { return value; }
protected:
static const uint8_t Val1 = 1;
static const uint8_t Val2 = 2;
static const uint8_t Val3 = 3;
uint8_t value;
};
const MyEnum MyEnum::VAL_1(Val1);
const MyEnum MyEnum::VAL_2(Val2);
const MyEnum MyEnum::VAL_3(Val3);
int main()
{
MyEnum e;
e = MyEnum::VAL_1;
if (e == MyEnum::VAL_1)
std::cout << "Compiles" << std::endl;
switch (e)
{
case MyEnum::VAL_1:
{
std::cout << "Doesn't compile" << std::endl;
}
}
exit(0);
}
Thanks for all your answers, as I stated in my first post, my issue is mainly on C++ enums inheritance, then please find below an updated example.
Currently I have 2 issues:
The first MyEnum class implementation stops working enabling toString() methods, just compile with -DTO_STRING and you can see the effect on e value. I understand i'm trying to do something ugly, is there a correct way to achieve the same result?
I have a bunch of code using functions that take MyEnum type as input and I cannot modify it. Using the second suggested MyEnum implementation that wraps real enum, just compile with -DMYENUM_2, I get an error because wrapped enum type (vale) is expected as function input, not MyEnum itself. Any ideas?
Thanks again.
#include <iostream>
#include <cstdint>
#ifndef MYENUM_2
class MyEnum
{
public:
static const MyEnum VAL_1;
static const MyEnum VAL_2;
static const MyEnum VAL_3;
MyEnum() {}
constexpr explicit MyEnum(uint8_t val) : value(val) {}
bool operator<(const MyEnum& other) const { return value < other.value; }
bool operator==(const MyEnum& other) const { return value == other.value; }
bool operator!=(const MyEnum& other) const { return !(operator==(other)); }
constexpr operator uint8_t() const { return value; }
#ifdef TO_STRING
virtual std::string toString()
{
printf("value = %d\n", value);
if (value == Val1)
return "1";
else if (value == Val2)
return "2";
else if (value == Val3)
return "3";
}
#endif
protected:
static const uint8_t Val1 = 1;
static const uint8_t Val2 = 2;
static const uint8_t Val3 = 3;
uint8_t value;
};
constexpr MyEnum MyEnum::VAL_1(Val1);
constexpr MyEnum MyEnum::VAL_2(Val2);
constexpr MyEnum MyEnum::VAL_3(Val3);
class MyDerivedEnum : public MyEnum
{
public:
static const MyDerivedEnum VAL_4;
static const MyDerivedEnum VAL_5;
static const MyDerivedEnum VAL_6;
MyDerivedEnum() {}
constexpr explicit MyDerivedEnum(uint8_t val) : MyEnum(val) {}
#ifdef TO_STRING
std::string toString()
{
printf("value = %d\n", value);
if (value == Val4)
return "4";
else if (value == Val5)
return "5";
else if (value == Val6)
return "6";
}
#endif
private:
static const uint8_t Val4 = 4;
static const uint8_t Val5 = 5;
static const uint8_t Val6 = 6;
};
constexpr MyDerivedEnum MyDerivedEnum::VAL_4(Val4);
constexpr MyDerivedEnum MyDerivedEnum::VAL_5(Val5);
constexpr MyDerivedEnum MyDerivedEnum::VAL_6(Val6);
#else
class MyEnum
{
public:
typedef enum
{
VAL_1 = 1,
VAL_2,
VAL_3
} vale;
MyEnum() {}
explicit MyEnum(uint8_t val) : value((vale)val) {}
virtual ~MyEnum() {}
bool operator<(const MyEnum& other) const { return value < other.value; }
bool operator==(const MyEnum& other) const { return value == other.value; }
bool operator!=(const MyEnum& other) const { return !(operator==(other)); }
//replaced by operator vale :
//operator uint8_t() const { return value; }
MyEnum& operator = (const vale& v)
{
value = v;
return *this;
}
operator vale () const
{
return value;
}
//op ==, !=... to be written
protected:
vale value;
};
#endif
class A
{
public:
A() {}
~A() {}
void set(MyEnum e)
{
printf("e = %d\n", e);
}
};
#ifndef MYENUM_2
class B : A
{
public:
B() {}
~B() {}
void test(MyDerivedEnum e)
{
set(e);
}
};
#endif
int main()
{
A a;
#ifndef MYENUM_2
B b;
#endif
a.set(MyEnum::VAL_1);
#ifndef MYENUM_2
b.test(MyDerivedEnum::VAL_4);
#endif
exit(0);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
对编译的轻微修改:
demo
Slight modifications to compiles:
Demo
使用Pete Becker的解决方案怎么办?添加枚举类型和相关的转换操作员 - ?你可以这样做
What about using Pete Becker' solution ? Add an enumerated type -and associated conversion operators- ? You can do it this way