Search code examples
c++c++11enumsenumerator

Enumerator initialization after declaration


Consider the following enumeration declaration :

enum Foo { Bar, Baz, Qux };

Now consider I want the enumerators (Bar, Baz and Qux) to have certain values. I can solve this by simply initializing them in the declaration :

enum Foo { Bar = 4, Baz = 2, Qux = 42 };

Now, what if I do not want these values to be known ? For exemple, when using other predefined values from other librairies, or when using the same value for two enumerators. Exemples :

enum Foo { Bar = MY_LIB_BAR, Baz = MY_LIB_BAZ, Qux = MY_LIB_QUX };
enum Foo { Bar = 0, Baz = 42, Qux = 0 };

I tried things like that :

// In header
enum Foo { Bar, Baz, Qux };
// In source
Foo { Bar = 0, Baz = 42, Qux = 0 };
// ...or...
Foo::Bar = 0, Foo::Baz = 42, Foo::Qux = 0;

Obviously, none of my attempts did work.

So, my question is as follows : is there a way to initialize enumerators outside of their declaration ? If so, how to do it, for exemple in a corresponding .cpp source file ?

EDIT : I can specify the underlying type of my enumeration. Considering that C++11 allows forward declaration, I thought that my problem could be solved since the enumeration becomes a complete type.


Solution

  • This is not possible. The reason is simple, for example, enums are often used in switch statements. For these statements, the constants must be known at compile time. If you could omit them in the header, then the compiler would be unable to compile any switch in another ocmpilation unit since it would have no access to the values.

    The same goes for all constexprs: They must be defined where they are declared for exactly the same reason: The compiler must always know their values.

    If you really need to hide away int constants, then simply define them as usual constants, e.g.:

    Foo.hpp:

    class Foo {
        static const int Bar;
        static const int Baz;
        static const int Qux;
    }
    

    Foo.cpp:

    const int Foo::Bar = 47;
    const int Foo::Baz = 11;
    const int Foo::Qux = 4711;
    

    Of course, you lose the ability to use these constants in a switch statement!

    I can specify the underlying type of my enumeration. Considering that C++11 allows forward declaration, I thought that my problem could be solved since the enumeration becomes a complete type.

    This does not help at all! Forward declaration of enum constants is simply not possible, even in C++11 and C++14.