为什么在 C++ 中声明枚举时使用 typedef?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/385023/
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 15:03:55  来源:igfitidea点击:

Why do you use typedef when declaring an enum in C++?

c++enumstypedef

提问by Tim Merrifield

I haven't written any C++ in years and now I'm trying to get back into it. I then ran across this and thought about giving up:

我已经很多年没有写过任何 C++ 了,现在我正在努力重新开始。然后我遇到了这个并考虑放弃:

typedef enum TokenType
{
    blah1   = 0x00000000,
    blah2   = 0X01000000,
    blah3   = 0X02000000
} TokenType;

What is this? Why is the typedefkeyword used here? Why does the name TokenTypeappear twice in this declaration? How are the semantics different from this:

这是什么?为什么typedef这里使用关键字?为什么这个名字TokenType在这个声明中出现了两次?语义与此有何不同:

enum TokenType
{
    blah1 = 0x00000000,
    blah2=0x01000000,
    blah3=0x02000000
};

回答by Ryan Fox

In C, declaring your enum the first way allows you to use it like so:

在 C 中,以第一种方式声明枚举允许您像这样使用它:

TokenType my_type;

If you use the second style, you'll be forced to declare your variable like this:

如果您使用第二种样式,您将被迫像这样声明您的变量:

enum TokenType my_type;

As mentioned by others, this doesn't make a difference in C++. My guess is that either the person who wrote this is a C programmer at heart, or you're compiling C code as C++. Either way, it won't affect the behaviour of your code.

正如其他人所提到的,这在 C++ 中没有区别。我的猜测是,要么编写此代码的人本质上是 C 程序员,要么您将 C 代码编译为 C++。无论哪种方式,它都不会影响您的代码的行为。

回答by mat

It's a C heritage, in C, if you do :

这是 C 的遗产,在 C 中,如果你这样做:

enum TokenType
{
    blah1   = 0x00000000,
    blah2   = 0X01000000,
    blah3   = 0X02000000
};

you'll have to use it doing something like :

你必须使用它做类似的事情:

enum TokenType foo;

But if you do this :

但如果你这样做:

typedef enum e_TokenType
{
    blah1   = 0x00000000,
    blah2   = 0X01000000,
    blah3   = 0X02000000
} TokenType;

You'll be able to declare :

您将能够声明:

TokenType foo;

But in C++, you can use only the former definition and use it as if it were in a C typedef.

但在 C++ 中,您只能使用前一个定义,并像在 C 类型定义中一样使用它。

回答by David Rodríguez - dribeas

You do not need to do it. In C (not C++) you were required to use enum Enumnameto refer to a data element of the enumerated type. To simplify it you were allowed to typedefit to a single name data type.

你不需要这样做。在 C(不是 C++)中,您需要使用enum Enumname来引用枚举类型的数据元素。为了简化它,您可以将其typedef为单一名称数据类型。

typedef enum MyEnum { 
  //...
} MyEnum;

allowed functions taking a parameter of the enum to be defined as

允许将枚举的参数定义为的函数

void f( MyEnum x )

instead of the longer

而不是更长

void f( enum MyEnum x )

Note that the name of the typename does not need to be equal to the name of the enum. The same happens with structs.

请注意,typename 的名称不需要与枚举的名称相同。结构体也是如此。

In C++, on the other hand, it is not required, as enums, classes and structs can be accessed directly as types by their names.

另一方面,在 C++ 中,它不是必需的,因为枚举、类和结构可以通过名称直接作为类型访问。

// C++
enum MyEnum {
   // ...
};
void f( MyEnum x ); // Correct C++, Error in C

回答by BeWarned

In C, it is good style because you can change the type to something besides an enum.

在 C 中,这是一种很好的风格,因为您可以将类型更改为枚举以外的其他内容。

typedef enum e_TokenType
{
    blah1   = 0x00000000,
    blah2   = 0X01000000,
    blah3   = 0X02000000
} TokenType;

foo(enum e_TokenType token);  /* this can only be passed as an enum */

foo(TokenType token); /* TokenType can be defined to something else later
                         without changing this declaration */

In C++ you can define the enum so that it will compile as C++ or C.

在 C++ 中,您可以定义枚举,以便将其编译为 C++ 或 C。

回答by Tim

Holdover from C.

来自 C 的保留。

回答by russbishop

Some people say C doesn't have namespaces but that is not technically correct. It has three:

有人说 C 没有命名空间,但这在技术上是不正确的。它有三个:

  1. Tags (enum, union, and struct)
  2. Labels
  3. (everything else)
  1. 标签 ( enum, union, 和struct)
  2. 标签
  3. (其他一切)

typedef enum { } XYZ;declares an anonymous enumeration and imports it into the global namespace with the name XYZ.

typedef enum { } XYZ;声明一个匿名枚举并将其导入到名为 的全局命名空间中XYZ

typedef enum ABC { } XYZ;declares an enum named ABCin the tag namespace, then imports it into the global namespace as XYZ.

typedef enum ABC { } XYZ;声明一个ABC在标记命名空间中命名的枚举,然后将其作为XYZ.

Some people don't want to bother with the separate namespaces so they typedef everything. Others never typedef because they want the namespacing.

有些人不想打扰单独的命名空间,所以他们对所有内容进行 typedef。其他人从不键入定义,因为他们想要命名空间。

回答by Francisco Orlandini

This is kind of old, but anyway, I hope you'll appreciate the link that I am about to type as I appreciated it when I came across it earlier this year.

这有点旧,但无论如何,我希望你会喜欢我即将输入的链接,因为我在今年早些时候遇到它时很感激它。

Here it is. I should quote the explanation that is always in my mind when I have to grasp some nasty typedefs:

这里。当我必须掌握一些讨厌的 typedef 时,我应该引用我脑海中一直存在的解释:

In variable declarations, the introduced names are instances of the corresponding types. [...] However, when the typedefkeyword precedes the declaration, the introduced names are aliases of the corresponding types

在变量声明中,引入的名称是相应类型的实例。[...] 但是,当typedef关键字位于声明之前时,引入的名称是相应类型的别名

As many people previously said, there is no need to use typedefs declaring enums in C++. But that's the explanation of the typedef's syntax! I hope it helps (Probably not OP, since it's been almost 10 years, but anyone that is struggling to understand these kind of things).

正如许多人之前所说,在C++ 中不需要使用 typedef 来声明枚举。但这就是 typedef 语法的解释!我希望它有所帮助(可能不是 OP,因为已经快 10 年了,但是任何努力理解这类事情的人)。

回答by AdRiX

In some C codestyle guide the typedef version is said to be preferred for "clarity" and "simplicity". I disagree, because the typedef obfuscates the real nature of the declared object. In fact, I don't use typedefs because when declaring a C variable I want to be clear about what the object actually is. This choice helps myself to remember faster what an old piece of code actually does, and will help others when maintaining the code in the future.

在一些 C 代码风格指南中,typedef 版本被认为是“清晰”和“简单”的首选。我不同意,因为 typedef 混淆了声明对象的真实性质。事实上,我不使用 typedefs,因为在声明 C 变量时我想清楚该对象实际上是什么。这个选择可以帮助我更快地记住一段旧代码实际上做了什么,并且会在以后维护代码时帮助其他人。

回答by AnT

The actual answer to the "why" question (which is surprisingly ignored by the existing answers top this old question) is that this enumdeclaration is probably located in a header file that is intended to be cross-compilable as both C and C++ code (i.e. included into both C and C++ implementation fiules). The art of writing such header files relies on the author's ability to select language features that have the proper compatible meaning in both languages.

“为什么”问题的实际答案(令人惊讶地被现有答案忽略了这个老问题)是这个enum声明可能位于一个头文件中,该头文件旨在作为 C 和 C++ 代码进行交叉编译(即包含在 C 和 C++ 实现文件中)。编写此类头文件的艺术依赖于作者选择在两种语言中具有适当兼容含义的语言功能的能力。