简体   繁体   English

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

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

I haven't written any C++ in years and now I'm trying to get back into it. 我多年没有写过任何C ++,现在我想回到它。 I then ran across this and thought about giving up: 然后我跑过去想着放弃:

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

What is this? 这是什么? Why is the typedef keyword used here? 为什么在这里使用typedef关键字? Why does the name TokenType appear twice in this declaration? 为什么名称TokenType在此声明中出现两次? How are the semantics different from this: 语义与此有何不同:

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

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++. 正如其他人所说,这对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++. 我的猜测是,写这篇文章的人要么是C程序员,要么是将C代码编译为C ++。 Either way, it won't affect the behaviour of your code. 无论哪种方式,它都不会影响代码的行为。

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 typedef。

You do not need to do it. 你不需要这样做。 In C (not C++) you were required to use enum Enumname to refer to a data element of the enumerated type. 在C(不是C ++)中,您需要使用枚举Enumname来引用枚举类型的数据元素。 To simplify it you were allowed to typedef it to a single name data type. 为了简化它,你被允许它的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. 请注意,typename的名称不必等于枚举的名称。 The same happens with structs. 结构也是如此。

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

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.

来自C的保留

Some people say C doesn't have namespaces but that is not technically correct. 有人说C没有命名空间,但技术上并不正确。 It has three: 它有三个:

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

typedef enum { } XYZ; declares an anonymous enumeration and imports it into the global namespace with the name XYZ . 声明一个匿名枚举,并将其导入名为XYZ的全局命名空间。

typedef enum ABC { } XYZ; declares an enum named ABC in the tag namespace, then imports it into the global namespace as 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. 其他人从不打字,因为他们想要命名空间。

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 typedef keyword 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++ . 正如许多人之前所说的那样,没有必要在C ++中使用typedef声明枚举。 But that's the explanation of the typedef's syntax! 但这是对typedef语法的解释! 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). 我希望它有所帮助(可能不是OP,因为它已经差不多10年了,但任何人都在努力理解这些事情)。

In some C codestyle guide the typedef version is said to be preferred for "clarity" and "simplicity". 在某些C codestyle指南中,typedef版本被认为是“清晰度”和“简单性”的首选版本。 I disagree, because the typedef obfuscates the real nature of the declared object. 我不同意,因为typedef模糊了声明对象的真实性质。 In fact, I don't use typedefs because when declaring a C variable I want to be clear about what the object actually is. 实际上,我不使用typedef,因为在声明C变量时我想清楚对象的实际内容。 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. 这种选择有助于我更快地记住旧代码实际执行的操作,并在将来维护代码时帮助其他人。

The actual answer to the "why" question (which is surprisingly ignored by the existing answers top this old question) is that this enum declaration is probably located in a header file that is intended to be cross-compilable as both C and C++ code (ie included into both C and C++ implementation fiules). “为什么”问题的实际答案(现有答案令人惊讶地忽略了这个老问题)是这个enum声明可能位于一个头文件中,该文件旨在作为C和C ++代码进行交叉编译(即包含在C和C ++实现文件中)。 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. 编写此类头文件的艺术依赖于作者选择在两种语言中具有适当兼容含义的语言功能的能力。

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM