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

我已经多年没有编写任何C ++,现在我正试图回到它。 然后我跑过去,想着放弃:

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

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

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

在C中,声明你的枚举的第一种方式可以让你像这样使用它:

 TokenType my_type; 

如果你使用第二种风格,你将被迫像这样声明你的variables:

 enum TokenType my_type; 

正如其他人所说,这在C ++中没有什么不同。 我的猜测是,无论是写这篇文章的人都是C程序员,还是将C代码编译为C ++。 无论哪种方式,它不会影响您的代码的行为。

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

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

你将不得不使用它做一些事情:

 enum TokenType foo; 

但是,如果你这样做:

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

你将能够声明:

 TokenType foo; 

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

你不需要这样做。 在C(而不是C ++)中,您需要使用枚举枚举来引用枚举types的数据元素。 为了简化它,你被允许键入一个单一的名称数据types。

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

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

 void f( MyEnum x ) 

而不是更长的时间

 void f( enum MyEnum x ) 

请注意,types名称的名称不需要等于枚举的名称。 结构也是如此。

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

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

在C中,这是很好的风格,因为你可以改变types除了枚举之外的东西。

 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 */ 

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

从C持有

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

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

  1. enum
  2. struct
  3. 全球(其他)

typedef enum { } XYZ; 声明一个匿名枚举并使用全局名称XYZ将其导入到全局名称空间中。

typedef enum ABC { } XYZ; 在枚举名称空间中声明名为ABC的枚举,然后将其作为XYZ导入到全局名称空间中。

enum XYZ x; 在枚举名称空间中声明一个XYZtypes的variables。

所有这一切同样适用于struct命名空间。

有些人不想打扰单独的命名空间,所以他们键入一切。 其他人从来没有typedef,因为他们想要命名空间。

这是旧的,但是无论如何,我希望你们能够欣赏我今年早些时候遇到的这个链接。

在这里。 我应该引用我一直在想的解释,当我必须去掌握一些令人讨厌的typedef时:

在variables声明中,引入的名称是相应types的实例。 […]但是,当typedef关键字在声明之前时,引入的名称是相应types的别名

正如很多人以前所说,不需要在C ++中使用typedefs声明枚举。 但是这是typedef语法的解释! 我希望它有帮助(可能不是OP,因为已经差不多有10年了,但是任何人都在努力去理解这些东西)。

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