首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >枚举类型是无范围的,更喜欢枚举类而不是枚举?

枚举类型是无范围的,更喜欢枚举类而不是枚举?
EN

Stack Overflow用户
提问于 2021-02-24 23:23:37
回答 2查看 4.8K关注 0票数 3

我是C++的新手,我想知道是否有人能帮我理解为什么

代码语言:javascript
复制
enum difficulty { NOVICE, EASY, NORMAL, HARD, UNBEATABLE };
difficulty myDiffiuclty = EASY

代码语言:javascript
复制
enum shipCost { FIGHTER_COST = 25, BOMBER_COST, CRUISER_COST = 50 };
shipCost myShipCost = BOMBER_COST;

用绿色划线?它说它更喜欢枚举类,但是当我将它更改为enum类时

代码语言:javascript
复制
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;

myShipCost以绿色下划线,BOMBER_COST为红色下划线,CRUISER_COST为红色下划线。

代码语言:javascript
复制
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;
EN

回答 2

Stack Overflow用户

发布于 2021-02-24 23:27:38

代码语言:javascript
复制
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时,对整数的隐式转换将被删除,必须对其中的常量进行调整。

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

代码语言:javascript
复制
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,就应该重命名它们:

代码语言:javascript
复制
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

但是,请注意,如果您只是使用它来创建常量,而不打算创建类型,请考虑使用以下内容:

代码语言:javascript
复制
namespace ship {
  namespace cost {
    constexpr int fighter = 25;
    constexpr int bomber = 30;
    constexpr int cruiser = 50;
  }
}

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

票数 8
EN

Stack Overflow用户

发布于 2022-02-05 23:46:41

既然你理解了不同之处,从上面的答案,我想指出几个地方,在那里,“新”的做事方式,以及你能做些什么。

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

代码语言:javascript
复制
typedef enum sample_type_e {
   sample_type_uint16,
   sample_type_double
}sample_type_t;

现在,要知道的第一件事是,这里不再需要ty清晰度;您可以在其他地方读到更多关于这个问题的信息。继续前进..。

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

现在,解决这一问题的一种方法似乎是采用新的语法--但是看看会发生什么:

代码语言:javascript
复制
enum class SampleType {
   uint16,
   double
}

糟了。

那是行不通的--双字是个保留字。现在,你可以愤怒地这样做:

代码语言:javascript
复制
enum class SampleType {
   uint16,
   type_double
}

...but是不太一致的,当你到达这里的时候:

代码语言:javascript
复制
enum class SampleType {
   type_uint16,
   type_double
}

可以说,...you已经实现了至少一个所谓的新功能的好处相反的地方:在可能的情况下保持简洁,而不会失去上下文。

在我所谓的人为但实际上是现实世界的例子中,最讨厌的是你不能找出一个保留的词:它们总是被保留的。(切点感兴趣:有些语言从来都不是真的.)

这就是所谓的“不幸”,它发生的频率比语言设计师们愿意承认的要多,而且当你没有他们中的一个和你在一起时,就会出现这种情况。

所以,如果这样的事情发生在你身上,而你真的不喜欢尝试使用“类枚举”的结果,你会怎么做?

实际上,您可能可以通过使用另一个被认为在任何可能的情况下使用的良好实践的语言特性来解决整个原始问题:名称空间。如果我只是命名空间--原始声明(减去残酷的ty清晰度)--我得到:

代码语言:javascript
复制
namespace audiostuff {
    enum sample_type_e {
       sample_type_uint16,
       sample_type_double
    };
};

只要使用该内容的任何代码都位于相同的命名空间中,或者具有...and

代码语言:javascript
复制
using namespace audiostuff;

在顶部,或者交替使用,如下所示:

代码语言:javascript
复制
audiostuff::sample_type_e my_sample_type_var;

...then,瞧,Visual不再抱怨了--其他编译器也应该这样做。

毕竟,抱怨是关于提醒你,你应该避免把全局名称空间弄乱--特别是偶然的。"class enum“是这样做的一种方法,但使用显式命名空间也是如此。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66360268

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档