为什么在结构中放入枚举然后使用typedef名称?

Tim*_*all 2 c++ enums c++03

我发现在我们公司的代码中使用了以下模式.

struct Foo
{
    enum FType
    {
        TypeA,
        TypeB,
        Type_MAX
    };
};
typedef Foo::FType FooType;
[...]
FooType m_type;
Run Code Online (Sandbox Code Playgroud)

我的问题是,这有什么好处?(或者,这避免了什么问题?)要明确,我想知道他们为什么不只是......

enum FooType
{
    TypeA,
    TypeB,
    Type_MAX
};
[...]
FooType m_type;
Run Code Online (Sandbox Code Playgroud)

我不能问原来的程序员,因为他们已被重新分配,事实证明我们公司的指定主题专家实际上是我.

如果它有帮助,这个代码已经在不同的时间使用许多版本的MSVC,gcc和clang编译为不同的目标平台...所有预先C++ 11.

谁能明白为什么这样做了?如果答案结果是微不足道的话,请提前道歉.

编辑添加:这是内部使用.(当枚举是全局的时,我们的样式指南要求条目以公共前缀开头,以便将它们与其他符号区分开.)

Pet*_*ker 5

普通旧枚举的感知问题是枚举数成为定义枚举的范围内的名称.结果,你可以说,例如,

FooType m_type;
m_type = TypeA;
Run Code Online (Sandbox Code Playgroud)

如果您还定义了类名,TypeA则会发生冲突.将枚举放在类中意味着您必须使用范围限定符来获取名称,这将消除冲突.这也意味着你必须写

FooType m_type;
m_type = FooType::TypeA;
Run Code Online (Sandbox Code Playgroud)

因为以前的版本无效.

这个问题的新解决方案是作用域:

enum class FooType {
    TypeA,
    TypeB,
    Type_MAX
};
Run Code Online (Sandbox Code Playgroud)

现在你可以说

FooType m_type;
m_type = FooType::TypeA;
Run Code Online (Sandbox Code Playgroud)

但不是

m_type = TypeA;
Run Code Online (Sandbox Code Playgroud)

正如@ Jarod42指出的那样,这里的一个区别是,由普通枚举定义的枚举器可以隐式转换为int,而来自作用域枚举的枚举器则不是.所以使用类中的定义,

int i = FooType::TypeA;
Run Code Online (Sandbox Code Playgroud)

是有效的,并i获取值0.使用作用域枚举它是无效的.

在这两种情况下,强制转换都可以使转换正常:

int i = static_cast<int>(FooType::TypeA);
Run Code Online (Sandbox Code Playgroud)