简体   繁体   English

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

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

当人们可以使用const时,为什么人们在 C++ 中使用枚举作为const

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

In older versions of C++, static const was not supported inside classes.在旧版本的 C++ 中,类内部不支持static const This meant that const was useless for constant expressions inside classes.这意味着const对于类中的常量表达式是无用的。 However, people still wanted to do this so a typical solution (usually referred to as the “enum hack”) was to use an untagged enum with no instances.然而,人们仍然希望这样做,因此一个典型的解决方案(通常称为“enum hack”)是使用没有实例的未标记enum 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; }

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 );
}

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

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.另一个可能的原因是,静态 const int 可能在运行时为其保留内存,而枚举永远不会为其保留实际内存位置,并将在编译时处理。 See this related question.请参阅此相关问题。

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一种类型的枚举不能隐式转换为另一种类型的枚举

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...循环适应...

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
    };
    ...
};

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?
{
   ...
}

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 = MONDAY than day_of_week = 1 .我知道我宁愿看到day_of_week = MONDAY也不愿看到day_of_week = 1

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 };
};

Using an enum documents the valid choices in a terse manner and allows the compiler to enforce them.使用枚举以简洁的方式记录有效的选择,并允许编译器强制执行它们。

If they are using enum store global constants, like Pi, for example, then I don't know what their goal is.如果他们使用枚举存储全局常量,例如 Pi,那么我不知道他们的目标是什么。

One reason is that const requires more typing:原因之一是const需要更多的输入:

enum { Val1, Val2, Val3 };

...versus... ...相对...

const int Val1=0, Val2=1, Val3=2;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 人们为什么在C ++中使用`main()`而不是`int main()`? - Why do people use `main()` instead of `int main()` in C++? 为什么人们在 C++ 中如此频繁地使用 __(双下划线) - Why do people use __ (double underscore) so much in C++ C ++完美转发:如果可以使用const_cast(),为什么还需要forward()? - C++ perfect forwarding: why do we need forward() if we can use const_cast()? C ++和C ++ 11类静态成员,double应该使用“constexpr”,而int可以是“const”,为什么? - C++ and C++11 class static member, double should use “constexpr” while int can be “const”, why? 如何在 C++ 中使用枚举 - How to use enums in C++ 不鼓励在C ++中使用常量吗? - Is the use of constants in C++ discouraged? 如何在 c++ 中使用带有函数的枚举? - How do I use enums with functions in c++? “for(;;)”比“while (TRUE)”快吗? 如果不是,人们为什么要使用它? - Is “for(;;)” faster than “while (TRUE)”? If not, why do people use it? 我应该在c ++中使用枚举或多个const作为非顺序常量吗? - Should I use an enum or multiple const for non-sequential constants in c++? 您可以对 C++ 中的 class 对象使用不同的常量吗? - Can you use different constants for class objects in C++?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM