Enumerations are a great idiom. They allow you to define a
type that is composed of a predefined set of values. The code becomes easier to
write, and test, is more readable, and is easier to maintain–benefits you’re
likely to love. For example, check out the listing below; by reading the code,
you’ll instantly understand that the first working day is Monday:

enum week_day {
    Mon, Tue, Wed, Thu, Fri, Sat, Sun
};


week_day first_work_day;
first_work_day = Mon;

However, programmers need to deal with large amounts of
code, in the order of hundreds of thousands to millions of lines. Therefore,
it’s very easy for you to forget names (of functions, classes, namespaces,
etc). Code-completion is a great tool to help programmers deal with the
plethora of names in current code—a feature most IDEs implement
in some fashion.

Code-completion

Code-completion helps programmers by showing them possible
ways to complete instruction(s). Type a few letters, and the environment
suggests one or more possibilities to complete the current instruction, similar
to what is shown in Figure A.

Figure A

A typical code-completion

The problem with code-completion is that it does not work
for enumerations. More to the point, when dealing with an enumerated type, how
do you know what set of values it’s composed of? You would like something
similar to Figure B.

Figure B

Enumerated completion

Unfortunately, this does not happen in any IDE I know of at
this time, and it’s very unlikely it will happen anytime soon. The good news is
that you can get pretty close to that using the following technique.

Namespaces vs. structures

In order to allow code-completion, simply surround your
enumeration in a namespace
or a struct. You’ll name the
structure/namespace as your enumeration, and give your enumeration a new name
(the simplest would be to call it type). An example is shown in Figure C.

Figure C

Namespace/struct

It’s that simple! Your fellow programmers and those using or
enhancing your code will certainly thank you for it. And the code will be even
more readable—every usage of your enumeration will be prefixed by its type—as
shown here:

// somewhere, in a distant header
namespace show {
    enum type {
        normal, hide, maximize, minimize, restore
    };
};

struct window {
    void show( ::show::type s);
    // ...
};

int main() {
    window w;
    // hide the window
    w.show(show::hide);

    // maximize the window
    w.show(show::maximize);
}

An even better benefit is when you have combination
enumerations: where a valid value could be a combination of states, as you see
in Figure D. By reading the code,
you can clearly tell that checked, enabled, and focused are possible states of
a check-box.

Figure D

You implement this technique using either a namespace (as I’ve shown you in the
previous examples), or by using a structure; both have pros and cons. The
advantages of namespaces include:

  • A namespace is open; you can add
    other new types/definitions to it
  • When
    using a namespace, no unneeded code is generated (when using a struct, some poor compilers might
    mistakenly generate the class’s default constructor, etc., even though
    they’re never needed)
  • They
    specify your intent in a more clear way: a namespace, as its name suggests, is a place where you collect
    names; a structure, on the other hand, is a collection of data. Thus,
    using a struct like shown above
    might be misleading to some programmers.

The drawbacks of namespaces include:

  • They
    cannot be used inside a class
  • You
    cannot inherit a namespace, like
    you can inherit a structure

In the light of the above, I recommend you use namespaces
where possible, and structures where you must.

When you want to make an enumeration part of a class, you’ll
implement something like this code:

struct check_box {
    // CANNOT use a namespace here
    struct state {
        enum type {
            checked = 1, enabled = 2, focused = 4, pressed = 8
        };
    };
    void set_state(int s);
    // ...
};


int main() {
    check_box c;
    c.set_state(check_box::state::checked |
check_box::state::enabled); }

The latter case is quite advanced and somewhat rare. It
occurs when you want to conceptually extend an enumeration, adding one or more
values to it. For example, you might want to add a new check-box state:
hot-tracked. Thus, you will extend the check_box
class, and the state enumeration as shown in Figure E.

Figure E

Extend the enumeration

Friendly enumerations

Enumerations are a very useful C++ construct. Using the
technique I’ve shown you, you can make them easier to use, read, and maintain.
In a word: friendlier.