枚举类型没有范围,更喜欢枚举类而不是枚举?

问题描述 投票:0回答:3

我是 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
3个回答
9
投票
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


1
投票

现在您已经从上面的答案中了解了其中的区别,我想指出一些“新”做事方式出现问题的地方,以及您可以采取哪些措施。

考虑一下我遇到的这个(缩写的)实际示例,将我用 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 不再抱怨了——其他编译器也应该如此。

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


0
投票
哇,没有什么反对原来的问题或答案,但是哇,我明白为什么这么多人转向 C#。这个问题简直就是废话,毫无意义。

我认为 C++ 标准的更改没有任何意义。

© www.soinside.com 2019 - 2024. All rights reserved.