【问题标题】:The enum type is unscoped prefer enum class over enum?enum 类型是 unscoped 更喜欢 enum 类而不是 enum?
【发布时间】:2021-02-24 23:23:37
【问题描述】:

我是 C++ 新手,我想知道是否有人可以帮助我理解原因

enum difficulty { NOVICE, EASY, NORMAL, HARD, UNBEATABLE };
difficulty myDiffiuclty = EASY

和

enum shipCost { FIGHTER_COST = 25, BOMBER_COST, CRUISER_COST = 50 };
shipCost myShipCost = BOMBER_COST;

有绿色下划线吗?它说它更喜欢枚举类,但是当我将其更改为枚举类时

enum class difficulty { NOVICE, EASY, NORMAL, HARD, UNBEATABLE };
difficulty myDiffiuclty = EASY;

enum class shipCost { FIGHTER_COST = 25, BOMBER_COST, CRUISER_COST = 50 };
shipCost myShipCost = BOMBER_COST;

EASY 变为红色下划线,并且 myShipCost 用绿色下划线,BOMBER_COST 用红色下划线,CRUISER_COST 用红色下划线

const int ALIEN_POINTS = 150;
int aliensKilled = 10;
int score = aliensKilled * ALIEN_POINTS;
cout << "score: " << score << endl;

enum difficulty { NOVICE, EASY, NORMAL, HARD, UNBEATABLE };
difficulty myDifficulty = EASY;

enum shipCost { FIGHTER_COST = 25, BOMBER_COST, CRUISER_COST = 50 };
shipCost myShipCost = BOMBER_COST;
cout << "\nTo upgrade my ship to a cruiser will cost "
    << (CRUISER_COST - myShipCost) << " Resource Points.\n";

system("pause");
return 0;

【问题讨论】:

    标签: c++ enums compiler-errors visual-studio-2019


    【解决方案1】:
    enum class difficulty { NOVICE, EASY, NORMAL, HARD, UNBEATABLE };
    difficulty myDiffiuclty = difficulty::EASY;
    
    enum class shipCost { FIGHTER_COST = 25, BOMBER_COST, CRUISER_COST = 50 };
    shipCost myShipCost = shipCost::BOMBER_COST;
    

    使用enum class,与整数的隐式转换被删除,并且你必须在其中限定常量。

    这被认为是一种改进。将其显式转换回整数仍然有效,但这不是偶然发生的。

    std::cout << "\nTo upgrade my ship to a cruiser will cost "
        << (static_cast<int>(shipCost::CRUISER_COST) - static_cast<int>(myShipCost)) <<
        " Resource Points.\n";
    
    system("pause");
    return 0;
    

    一旦你使用enum class,你应该重命名它们:

    enum class difficulty { novice, easy, normal, hard, unbeatable };
    difficulty myDiffiuclty = difficulty::easy;
    
    enum class shipCost { fighter =25, bomber=30, cruiser = 50 };
    shipCost myShipCost = shipCost::bomber;
    

    由于名称的ship 部分现在在enum 中,因此无需在常量中重复。同样,由于名称是有范围的,您不必SHOUT 他们。

    但是请注意,如果您只是使用它来创建常量而不打算创建类型,请考虑使用类似的东西:

    namespace ship {
      namespace cost {
        constexpr int fighter = 25;
        constexpr int bomber = 30;
        constexpr int cruiser = 50;
      }
    }
    

    现在我们将 ship::cost::fighter 作为编译时计算的 int,而不是 enum class。

    【讨论】:

      【解决方案2】:

      现在您已经了解了区别,从上面的答案中,我想指出几个“新”做事方式出现问题的地方,以及您可以做些什么。

      考虑一下我遇到的这个(缩写)实际示例,将我用 C 编写的一些音频软件移植到现代 C++(C++17):

      typedef enum sample_type_e {
         sample_type_uint16,
         sample_type_double
      }sample_type_t;
      

      现在,首先要知道的是这里的 typedef 不再需要了;您可以在其他地方阅读更多相关信息。继续……

      此代码在 Visual Studio 2019 中编译,会导致您描述的错误。

      现在,一种 解决此问题的方法似乎 是转向新的语法——但请注意会发生什么:

      enum class SampleType {
         uint16,
         double
      }
      

      哎呀。

      这是行不通的——double 是保留字。现在,你可以愤怒地这样做:

      enum class SampleType {
         uint16,
         type_double
      }
      

      ...但这不是很一致,当你得到这个时:

      enum class SampleType {
         type_uint16,
         type_double
      }
      

      ...可以说,您已经实现了与此新功能的至少一个声称的好处完全相反的结果:尽可能简洁,而不会丢失上下文。

      在我所谓的人为但实际上是真实世界的示例中,令人讨厌的是您无法限定保留字:它们是始终保留的。 (切线兴趣点:有些语言永远不正确......)

      这叫做“倒霉”;它发生的频率比语言设计者愿意承认的要多得多,而且当你没有一个人在房间里时,它总是会出现。

      所以,如果你遇到了类似的情况,而你只是真的不喜欢尝试使用“类枚举”的结果,你会怎么做怎么办?

      好吧,事实证明,您可能可以通过使用 另一个 语言功能来解决整个原始问题,该功能被认为是尽可能使用的好习惯:命名空间。如果我只是命名该原始声明(减去繁琐的 typedef),我会得到:

      namespace audiostuff {
          enum sample_type_e {
             sample_type_uint16,
             sample_type_double
          };
      };
      

      ...只要任何使用这些东西的代码要么在同一个命名空间中,要么有

      using namespace audiostuff;
      

      在顶部,或者,使用是这样的:

      audiostuff::sample_type_e my_sample_type_var;
      

      ...然后,你瞧,Visual Studio 不再抱怨了——其他编译器也应该如此。

      毕竟,抱怨是为了提醒您应该避免弄乱全局命名空间——尤其是意外。 “类枚举”是一种方法,但使用显式命名空间也是如此。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-02-05
        • 1970-01-01
        • 1970-01-01
        • 2013-09-15
        • 1970-01-01
        • 1970-01-01
        • 2022-06-14
        相关资源
        最近更新 更多