为什么人们在使用const时使用C++中的枚举作为常量?

Loa*_*ati 33 c++ enums enumeration

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

Bas*_*ard 45

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

在旧版本的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;
}
Run Code Online (Sandbox Code Playgroud)

[编辑]

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


小智 36

枚举是不同的类型,所以你可以做类型导向的事情,比如用它们重载:

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

void f( Color c ) {
}

void f( Size s ) {
}

int main() {
    f( Red );
    f( Big );
}
Run Code Online (Sandbox Code Playgroud)

  • 这不是问题所在.问题是:为什么人们会这样写:enum {Margin = 50}; (6认同)

duf*_*ymo 23

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

  • 嗯,这看起来不像问题的答案(虽然它已被接受).人们使用枚举,他们可以使用`const`,而且**与**不相关.通常你会看到`enum {SOMETHING = 2232; }`(像那样;只有一个值的未命名的枚举)而不是`const int SOMETHING = 2232;`.这是因为enum永远不会得到任何存储,而const变量仍然是一个变量,并且如果编译器无法证明它将获得(静态)存储它将不需要它,而它通常不能. (34认同)

Ecl*_*pse 20

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

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

template <>
struct foo<0>
{
    enum { Value = 0; }
};
Run Code Online (Sandbox Code Playgroud)

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

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

template <>
struct foo<0>
{
    static const int Value = 0;
};
Run Code Online (Sandbox Code Playgroud)

另一个可能的原因是静态const int可能在运行时为它保留了内存,而枚举永远不会为它保留实际的内存位置,并且将在编译时处理.看到这个相关的问题.


ASk*_*ASk 10

使用时,枚举更具描述性.考虑:

int f(int fg, int bg)
Run Code Online (Sandbox Code Playgroud)

 int f(COLOR fg, COLOR bg)
Run Code Online (Sandbox Code Playgroud)

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

  • 整数不能隐式转换为枚举类型
  • 一种类型的枚举不能隐式转换为另一种类型的枚举

  • "整数不能隐式转换为枚举类型","一种类型的枚举不能隐式转换为另一种类型的枚举" - 假.简单的`enum`s将静默地转换为/从整数转换为C++,因此它们严格_don't_提供这种安全性.但是,在C++ 11中,有一个`enum class`,这是一个适当的C++风格"重新想象"`enum`:隐式转换已经消失了,另外值名必须始终是合格的.这与C#`enum`s类似,避免了C的旧`enum`引起的名称冲突/命名空间污染问题. (4认同)

Fea*_*eep 10

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

enum {NONE, START, HEY, HO, LAST};
Run Code Online (Sandbox Code Playgroud)

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

for (int i = NONE; i < LAST; i++)
{
    // Do stuff...
}
Run Code Online (Sandbox Code Playgroud)

添点什么...

enum {NONE, START, HEY, WEE, HO, LAST};
Run Code Online (Sandbox Code Playgroud)

循环适应......

  • 除非有人意外地将新的枚举文字添加到列表的末尾,或者决定为文字提供非连续的值(例如 enum {} NONE = 0、START = 4、HEY = 7 等......)。 (2认同)

Chi*_*ang 5

在编译器供应商实现ISO/IEC 14882:1998 C++标准之前,此代码在类范围中定义常量会导致编译错误:

class Foo {
    static const int MAX_LEN = 80;
    ...
};
Run Code Online (Sandbox Code Playgroud)

如果常量是一个整数类型,那么kludgy可以在类中的枚举中定义它:

class Foo {
    enum {
        MAX_LEN = 80
    };
    ...
};
Run Code Online (Sandbox Code Playgroud)