C++中的typedef枚举和普通枚举

11

这两个之间究竟有什么区别:

typedef enum {
  something1,
  something2,
  .....
  somethingN
} myEnum;

结束正好

enum myEnum{
  something1,
  something2,
  .....
  somethingN
};

我知道第一种情况下我使用了未命名的枚举类型,当然,我只是想知道哪种方法更好,以及为什么?


现在有了C++11,你不应该再使用enum。选择enum class更加安全。 - leftaroundabout
1
虽然enum class肯定是一种改进,但并不完全替代。它提供了两个功能(强制作用域和无隐式转换),但有时你只想要其中一个。 - R. Martinho Fernandes
@leftaroundabout:这并没有回答原问题,只是把它重定向到其他地方。 - SasQ
3个回答

19

第一种变体对于C语言非常有用,因为否则你需要在每个想要使用它的地方写enum myEnum

在C++中不是这种情况。 所以,据我所知,在C++中没有第一种情况的好处(除非你正在定义需要与C共享的接口等)。


16

没有区别。实际上,第一个版本是C风格编码。

C++11引入了强类型枚举,定义方式如下:

enum class myEnum  //note the 'class' keyword after the 'enum' keyword
{   
  something1,
  something2,
  .....
  somethingN
};

在 C++03 中,枚举类型不是类型安全的,它们本质上是整数,并且可以隐式地混合使用其他整数类型,另一个问题是它们没有作用域;您可以在不限定其类型的情况下使用其成员;您可以使用 something1。而 C++11 的强类型枚举是类型安全的,并且它们有作用域;您必须使用 myEnum::something1


1
在C++03中并没有你所说的那么糟糕。枚举确实定义了一种独特的类型,你可以在它们上面进行重载,并且你可以使用它们来定义重载运算符。隐式转换为整数类型可能有点麻烦,但我在实践中并没有发现这是一个问题。 - James Kanze
1
作用域从来都不是一个问题。namespace scope_for_my_enum { enum { foo, bar }; },或者 class scope_for_my_enum { enum { foo, bar }; };,这取决于你是否允许客户端省略它。实际上,这意味着旧的枚举在作用域方面更加灵活。 - R. Martinho Fernandes
1
@R.MartinhoFernandes: 这是一个权宜之计,默许了C++03枚举的作用域问题,这正是你想出这种解决办法的原因。而且,如果你使用这样的作用域解决方案,可读性会大大降低。 - Nawaz
@R.MartinhoFernandes:你之前的评论并不是关于“主要”的。无论如何,我已经编辑过了。 - Nawaz
1
我认为主要的动机是人们希望枚举常量有作用域(在某些情况下——并非总是)。除此之外,有一个普遍趋势是减少隐式转换(尽管那已经为时已晚)。 - James Kanze
显示剩余2条评论

1
我不会使用第一个。它与另一个几乎相同。在C++11中,使用第二个可以编写myEnum::something1,但是使用第一个则不行。此外,在某些情况下,您可以在C++11中前向声明枚举,但是无法前向声明未命名类型,并且也无法前向声明typedef。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接