与实施枚举的类的交换机/案例语句的问题(要派生)

发布于 2025-02-09 08:03:51 字数 5165 浏览 2 评论 0原文

在网上进行了一些搜索之后,我至少发现了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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

残月升风 2025-02-16 08:03:51

对编译的轻微修改:

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

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

demo

Slight modifications to compiles:

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

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

Demo

瑾兮 2025-02-16 08:03:51

使用Pete Becker的解决方案怎么办?添加枚举类型和相关的转换操作员 - ?你可以这样做

#include <iostream>
#include <cstdint>

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

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 << "compiles now" << std::endl;
     break;
  }
  exit(0);
}

What about using Pete Becker' solution ? Add an enumerated type -and associated conversion operators- ? You can do it this way

#include <iostream>
#include <cstdint>

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

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 << "compiles now" << std::endl;
     break;
  }
  exit(0);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文