为什么人们在使用const
时会将C ++中的枚举用作常量?
答案 0 :(得分:44)
布鲁斯·埃克尔在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; }
[编辑]
我认为将Bruce Eckel的网站链接起来会更公平:http://www.mindview.net/Books/TICPP/ThinkingInCPP2e.html。
答案 1 :(得分:36)
枚举是不同的类型,因此您可以执行类型导向的操作,例如使用它们进行重载:
enum Color { Red,Green,Blue };
enum Size { Big,Little };
void f( Color c ) {
}
void f( Size s ) {
}
int main() {
f( Red );
f( Big );
}
答案 2 :(得分:23)
枚举意味着一组相关的常量,因此有关该关系的附加信息必须在他们手头的问题模型中有用。
答案 3 :(得分:20)
处理模板元编程时也有历史原因。有些编译器可以使用枚举中的值,但不能使用静态const int来实例化类。
template <int N>
struct foo
{
enum { Value = foo<N-1>::Value + N };
};
template <>
struct foo<0>
{
enum { Value = 0; }
};
现在你可以用更明智的方式做到这一点:
template <int N>
struct foo
{
static const int Value = foo<N-1>::Value + N;
};
template <>
struct foo<0>
{
static const int Value = 0;
};
另一个可能的原因是,静态const int可能在运行时为它保留了内存,而枚举永远不会为它保留实际的内存位置,并且将在编译时处理。见this related question.
答案 4 :(得分:10)
枚举在使用时更具描述性。考虑:
int f(int fg, int bg)
与
int f(COLOR fg, COLOR bg)
此外,enums提供了更多类型安全性,因为
答案 5 :(得分:10)
我喜欢可以与枚举一起使用的自动行为,例如:
enum {NONE, START, HEY, HO, LAST};
然后很容易循环到LAST,并且当添加新状态(或任何表示的)时,逻辑会适应。
for (int i = NONE; i < LAST; i++)
{
// Do stuff...
}
添加内容......
enum {NONE, START, HEY, WEE, HO, LAST};
循环适应......
答案 6 :(得分:5)
在编译器供应商实现ISO / IEC 14882:1998 C ++标准之前,在类范围内定义常量的此代码导致编译错误:
class Foo {
static const int MAX_LEN = 80;
...
};
如果常量是一个整数类型,那么解决这个问题就是在类中的枚举中定义它:
class Foo {
enum {
MAX_LEN = 80
};
...
};
答案 7 :(得分:4)
枚举也可以用作类型名称。因此,您可以定义一个将枚举作为参数的函数,这使得更清楚应该将哪些值作为函数的参数给出,与将值定义为const变量并且函数仅接受“int”的函数相比较作为一个论点。
考虑:
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
{
...
}
与
int const baz = 0;
int const meh = 1;
void foo (int bar) // what are valid values for bar?
{
...
}
答案 8 :(得分:2)
在调试时,某些调试器将显示枚举名称而不是其值。这可能非常有用。我知道我希望看到day_of_week = MONDAY
而不是day_of_week = 1
。
答案 9 :(得分:2)
部分原因是较旧的编译器不支持声明真正的类常量
class C
{
const int ARealConstant = 10;
};
所以必须这样做
class C
{
enum { ARealConstant = 10 };
};
出于这个原因,许多便携式图书馆继续使用这种形式。
另一个原因是枚举可以用作方便的句法设备来将类常量组织成相关的那些,而那些不是
class DirectorySearcher
{
enum options
{
showFiles = 0x01,
showDirectories = 0x02,
showLinks = 0x04,
};
};
VS
class Integer
{
enum { treatAsNumeric = true };
enum { treatAsIntegral = true };
enum { treatAsString = false };
};
答案 10 :(得分:0)
使用枚举以简洁的方式记录有效选项,并允许编译器强制执行它们。
如果他们使用枚举存储全局常量,例如Pi,那么我不知道他们的目标是什么。
答案 11 :(得分:-1)
一个原因是const
需要更多输入:
enum { Val1, Val2, Val3 };
...与...
const int Val1=0, Val2=1, Val3=2;