Why put an enum in a struct and then use a typedef name?

  • A+

I've found the following pattern used fairly commonly in our company's code.

struct Foo {     enum FType     {         TypeA,         TypeB,         Type_MAX     }; }; typedef Foo::FType FooType; [...] FooType m_type; 

My question is, what is the benefit of this? (Or, what problem does this avoid?) To be clear, I am wondering why they didn't just...

enum FooType {     TypeA,     TypeB,     Type_MAX }; [...] FooType m_type; 

I can't ask the original programmer because they have been re-assigned, and it turns out that the designated subject matter expert in our company is, in fact, me.

If it helps, this code has been compiled at various times using many versions of MSVC, gcc, and clang for different target platforms... all pre C++11.

Can anyone see why this was done? Apologies in advance, if the answer turns out to be something trivial.


The perceived problem with plain old enums is that the enumerators become names in the scope where the enum is defined. As a result, you could say, for example,

FooType m_type; m_type = TypeA; 

If you had also defined a class names TypeA you'd have a conflict. Putting the enum inside a class means you have to use a scope qualifier to get at the name, which would remove the conflict. It also means you'd have to write

FooType m_type; m_type = FooType::TypeA; 

because the previous version wouldn't be valid.

A newer solution to this problem is scoped enums:

enum class FooType {     TypeA,     TypeB,     Type_MAX }; 

Now you can say

FooType m_type; m_type = FooType::TypeA; 

but not

m_type = TypeA; 

One difference here, as @Jarod42 points out, is that an enumerator defined by a plain enum can be implicitly converted to int, while an enumerator from a scoped enum is not. So with the definition inside a class,

int i = FooType::TypeA; 

is valid, and i gets the value 0. With a scoped enum it is not valid.

In both cases, a cast makes the conversion okay:

int i = static_cast<int>(FooType::TypeA); 


:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: