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

时间:2008-12-21 22:02:01

标签: c++ enums typedef

我多年没有编写任何C ++,现在我正试图重新开始。然后我跑过去想着放弃:

typedef enum TokenType
{
    blah1   = 0x00000000,
    blah2   = 0X01000000,
    blah3   = 0X02000000
} TokenType;
这是什么?为什么typedef关键字在这里使用?为什么名称TokenType在此声明中出现两次?语义与此有何不同:

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

9 个答案:

答案 0 :(得分:145)

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

TokenType my_type;

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

enum TokenType my_type;

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

答案 1 :(得分:90)

如果你这样做,那就是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。

答案 2 :(得分:19)

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

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

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

void f( MyEnum x )

而不是更长的

void f( enum MyEnum x )

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

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

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

答案 3 :(得分:10)

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

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

答案 4 :(得分:6)

来自C的保留。

答案 5 :(得分:5)

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

  1. 代码(enumunionstruct
  2. 标签
  3. (其他一切)
  4. typedef enum { } XYZ;声明一个匿名枚举,并将其导入名为XYZ的全局命名空间。

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

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

答案 6 :(得分:3)

这有点老了,但无论如何,我希望你能够理解我打算输入的链接,因为我在今年早些时候遇到它时对此表示赞赏。

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

  

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

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

答案 7 :(得分:1)

在某些C codestyle指南中,typedef版本被认为是" clear"和"简单"。 我不同意,因为typedef模糊了声明对象的真实性质。事实上,我不使用typedef,因为在声明一个C变量时我想清楚该对象实际上是什么。 这个选择有助于我更快地记住旧代码实际执行的操作,并在将来维护代码时帮助其他人。

答案 8 :(得分:1)

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