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

Tim*_*eld 174 c++ enums typedef

我多年没有写过任何C++,现在我想回到它.然后我跑过去想着放弃:

typedef enum TokenType
{
    blah1   = 0x00000000,
    blah2   = 0X01000000,
    blah3   = 0X02000000
} TokenType;
Run Code Online (Sandbox Code Playgroud)

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

enum TokenType
{
    blah1 = 0x00000000,
    blah2=0x01000000,
    blah3=0x02000000
};
Run Code Online (Sandbox Code Playgroud)

Rya*_*Fox 150

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

TokenType my_type;
Run Code Online (Sandbox Code Playgroud)

如果你使用第二种风格,你将被迫声明你的变量:

enum TokenType my_type;
Run Code Online (Sandbox Code Playgroud)

正如其他人所说,这对C++没有任何影响.我的猜测是,写这篇文章的人要么是C程序员,要么是将C代码编译为C++.无论哪种方式,它都不会影响代码的行为.

  • 您的问题仅适用于C,但不适用于C++.在C++中,枚举和结构可以直接使用,就像有一个typedef一样. (12认同)
  • 嗯,是的,但这确实回答了被问到的真正的问题,这真的是"这甚至意味着什么?" (7认同)
  • 这两者都是.你也可以说:enum TokenType_ {...}; typedef enum TokenType_ TokenType; (5认同)

mat*_*mat 95

如果您这样做,它是C语言中的C遗产:

enum TokenType
{
    blah1   = 0x00000000,
    blah2   = 0X01000000,
    blah3   = 0X02000000
};
Run Code Online (Sandbox Code Playgroud)

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

enum TokenType foo;
Run Code Online (Sandbox Code Playgroud)

但是如果你这样做:

typedef enum e_TokenType
{
    blah1   = 0x00000000,
    blah2   = 0X01000000,
    blah3   = 0X02000000
} TokenType;
Run Code Online (Sandbox Code Playgroud)

你将能够声明:

TokenType foo;
Run Code Online (Sandbox Code Playgroud)

但是在C++中,您只能使用前一个定义并将其用作C typedef.

  • 不是我在上一句话中说的话吗? (45认同)
  • @mat我赞成您对最后一句话的评论,但为公平起见,它的措辞不佳且令人困惑。 (2认同)

Dav*_*eas 20

你不需要这样做.在C(不是C++)中,您需要使用枚举Enumname来引用枚举类型的数据元素.为了简化它,你被允许的typedef它一个名称的数据类型.

typedef enum MyEnum { 
  //...
} MyEnum;
Run Code Online (Sandbox Code Playgroud)

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

void f( MyEnum x )
Run Code Online (Sandbox Code Playgroud)

而不是更长的

void f( enum MyEnum x )
Run Code Online (Sandbox Code Playgroud)

请注意,typename的名称不必等于枚举的名称.结构也是如此.

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

// C++
enum MyEnum {
   // ...
};
void f( MyEnum x ); // Correct C++, Error in C
Run Code Online (Sandbox Code Playgroud)


BeW*_*ned 11

在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 */
Run Code Online (Sandbox Code Playgroud)

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


Tim*_*Tim 6

来自C的保留


rus*_*hop 5

有人说C没有命名空间,但技术上并不正确.它有三个:

  1. 标签(enum,union,和struct)
  2. 标签
  3. (其他一切)

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

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

有些人不想打扰单独的命名空间,因此他们输入了所有内容.其他人从不打字,因为他们想要命名空间.


小智 5

这有点旧了,但无论如何,我希望您会欣赏我即将输入的链接,就像我今年早些时候遇到它时欣赏它一样。

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

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

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