为什么人们在 C++ 中使用枚举作为常量而他们可以使用 const?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/899917/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 17:51:21  来源:igfitidea点击:

Why do people use enums in C++ as constants while they can use const?

c++enumsenumeration

提问by Loai Nagati

Why do people use enums in C++ as constants when they can use const?

为什么人们可以使用 C++ 中的枚举作为常量const

采纳答案by duffymo

An enumeration implies a set of relatedconstants, so the added information about the relationship must be useful in their model of the problem at hand.

枚举意味着一组相关的常量,因此关于关系的附加信息必须对他们手头问题的模型有用。

回答by Bastien Léonard

Bruce Eckel gives a reason in Thinking in C++:

Bruce Eckel 在Thinking in C++ 中给出了一个理由:

In older versions of C++, static constwas not supported inside classes. This meant that constwas useless for constant expressions inside classes. However, people still wanted to do this so a typical solution (usually referred to as the “enum hack”) was to use an untagged enumwith no instances. An enumeration must have all its values established at compile time, it's local to the class, and its values are available for constant expressions. Thus, you will commonly see:

#include <iostream>
using namespace std;

class Bunch {
  enum { size = 1000 };
  int i[size];
};

int main() {
  cout << "sizeof(Bunch) = " << sizeof(Bunch) 
       << ", sizeof(i[1000]) = " 
       << sizeof(int[1000]) << endl;
}

在旧版本的 C++ 中,static const类内部不支持。这意味着const对于类中的常量表达式是无用的。然而,人们仍然想要这样做,所以一个典型的解决方案(通常称为“枚举黑客”)是使用enum没有实例的未标记。枚举必须在编译时建立其所有值,它是类的本地值,并且其值可用于常量表达式。因此,您通常会看到:

#include <iostream>
using namespace std;

class Bunch {
  enum { size = 1000 };
  int i[size];
};

int main() {
  cout << "sizeof(Bunch) = " << sizeof(Bunch) 
       << ", sizeof(i[1000]) = " 
       << sizeof(int[1000]) << endl;
}

[Edit]

[编辑]

I think it would be more fair to link Bruce Eckel's site: http://www.mindview.net/Books/TICPP/ThinkingInCPP2e.html.

我认为链接 Bruce Eckel 的网站会更公平:http: //www.mindview.net/Books/TICPP/ThinkingInCPP2e.html

回答by Bastien Léonard

Enums are distinct types, so you can do type-oriented things like overloading with them:

枚举是不同的类型,因此您可以执行面向类型的操作,例如重载它们:

enum Color { Red,Green,Blue };
enum Size { Big,Little };

void f( Color c ) {
}

void f( Size s ) {
}

int main() {
    f( Red );
    f( Big );
}

回答by Eclipse

There's a historical reason too when dealing with template metaprogramming. Some compilers could use values from an enum, but not a static const int to instantiate a class.

在处理模板元编程时也有一个历史原因。一些编译器可以使用枚举中的值,但不能使用静态 const int 来实例化类。

template <int N>
struct foo
{
    enum { Value = foo<N-1>::Value + N };
};

template <>
struct foo<0>
{
    enum { Value = 0; }
};

Now you can do it the more sensible way:

现在你可以用更明智的方式做到这一点:

template <int N>
struct foo
{
    static const int Value = foo<N-1>::Value + N;
};

template <>
struct foo<0>
{
    static const int Value = 0;
};

Another possible reason, is that a static const int may have memory reserved for it at runtime, whereas an enum is never going to have an actual memory location reserved for it, and will be dealt at compile time. See this related question.

另一个可能的原因是,静态 const int 可能在运行时为其保留内存,而枚举永远不会为其保留实际内存位置,并将在编译时处理。请参阅此相关问题。

回答by ASk

Enums are more descriptive when used. Consider:

枚举在使用时更具描述性。考虑:

int f(int fg, int bg)

versus

相对

 int f(COLOR fg, COLOR bg)

In addition, enums give a bit more type-safety, because

此外,枚举提供了更多的类型安全性,因为

  • integers are not implicitly convertible to enum types
  • enum of one type is not implicitly convertible to enum of another type
  • 整数不能隐式转换为枚举类型
  • 一种类型的枚举不能隐式转换为另一种类型的枚举

回答by FeatureCreep

I like the automatic behavior that can be used with enums, for example:

我喜欢可以与枚举一起使用的自动行为,例如:

enum {NONE, START, HEY, HO, LAST};

Then it is easy to loop until LAST, and when a new state (or whatever is represented) is added, the logic adapts.

然后很容易循环到 LAST,并且当添加新状态(或任何表示的状态)时,逻辑会适应。

for (int i = NONE; i < LAST; i++)
{
    // Do stuff...
}

Add something...

添点什么...

enum {NONE, START, HEY, WEE, HO, LAST};

The loop adapts...

循环适应...

回答by Chin Huang

Before compiler vendors implemented the ISO/IEC 14882:1998 C++ standard, this code to define a constant in a class scope resulted in a compile error:

在编译器供应商实施 ISO/IEC 14882:1998 C++ 标准之前,这段在类范围内定义常量的代码导致编译错误:

class Foo {
    static const int MAX_LEN = 80;
    ...
};

If the constant is an integer type, a kludgy work around is define it in an enum inside the class:

如果常量是整数类型,一个笨拙的解决方法是在类内的枚举中定义它:

class Foo {
    enum {
        MAX_LEN = 80
    };
    ...
};

回答by Dan Moulding

enums also can be used as a type name. So you can define a function that takes an enum as a parameter, which makes it more clear what kinds of values should be given as arguments to the function, as compared to having the values defined as const variables and the function accepting just "int" as an argument.

枚举也可以用作类型名称。因此,您可以定义一个将枚举作为参数的函数,与将值定义为 const 变量并且函数仅接受“int”相比,这更清楚应该将哪些类型的值作为函数的参数作为论据。

Consider:

考虑:

enum my_new_fangled_type {
  baz = 0,
  meh = 1
};

void foo (my_new_fangled_type bar) // bar can be a value listed in the enum
{
   ...
}

versus:

相对:

int const baz = 0;
int const meh = 1;

void foo (int bar) // what are valid values for bar?
{
   ...
}

回答by Trent

Some debuggers will show the enumeration name instead of its value when debugging. This can be very helpful. I know that I would rather see day_of_week = MONDAYthan day_of_week = 1.

某些调试器在调试时会显示枚举名称而不是其值。这可能非常有帮助。我知道,我宁愿看day_of_week = MONDAY不是day_of_week = 1

回答by DannyT

It's partly because older compilers did not support the declaration of a true class constant

部分原因是旧的编译器不支持真正的类常量的声明

class C
{
  const int ARealConstant = 10;
};

so had to do this

所以必须这样做

class C
{
  enum { ARealConstant = 10 };
};

For this reason, many portable libraries continue to use this form.

出于这个原因,许多便携式库继续使用这种形式。

The other reason is that enums can be used as a convenient syntactic device to organise class constants into those that are related, and those that are not

另一个原因是枚举可以作为一种方便的句法工具,将类常量组织成相关的和不相关的。

class DirectorySearcher
{
  enum options
  {
    showFiles = 0x01,
    showDirectories = 0x02,
    showLinks = 0x04,
  };
};

vs

对比

class Integer
{
   enum { treatAsNumeric = true };
   enum { treatAsIntegral = true };
   enum { treatAsString = false };
};