Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

enum vs static consts

Tags:

c++

enums

c++03

I am currently thinking about the question if namespaced enums or namespaced groups of static consts are preferable. What should be the default choice and why?

Option 1:

namespace Direction
{
    enum Direction
    {
        north,
        east,
        south,
        west,
    };
}

Option 2:

namespace Direction
{
    static const unsigned char north = 0;
    static const unsigned char east = 1;
    static const unsigned char south = 2;
    static const unsigned char west = 3;
}

Both have their advantages and disadvantages.

Pro enum:

  1. some typesafety:

    void foo(Direction dir); // the compiler won't allow you to just pass an int or a value of an unrelated enum without explicitly casting it
    

Contra enum:

  1. type safety is rather limited:

    enum A
    {
        Entry1 = 1
    };
    
    enum B
    {
        Entry2 = 10
    };
    
    A a;
    if(a == Entry2)
        ; // ouch!
    
  2. no support for any other type than int - before C++ 11 one can't just have an enum of for example long long, short or char

  3. the namespacing for enums is suboptimal

    1. if one doesn't wrap an enum into a separate namespace, then all its members will pollute the surrounding namespace.

    2. if one does wrap the enum into a separate namespace, then one gets some redundancy when using the enum itself as a type: One then has to declare a direction variable in the way Direction::Direction (when not doing a "using Direction::Direction", which would let them again pollute the outer namespace (at last in that part of the code, where the using directive takes effect)), to get able to namespace its members in the way Direction::north instead of just north

Pro static const:

  1. better type support in C++ prior to C++ 11 - one can for example use types like unsigned char for the constants
  2. proper scoping - no pollution of the outer namespace, without explicitly asking for it via a using directive (and even then only in a limited scope)

Contra static const:

  1. even less type safety than enums - one is no longer able to declare a function prototype like this:

    void foo(Direction dir);
    

    but would have to do it in the following way:

    void foo(unsigned char dir); // now each variable of type unsigned char or of a type that can implicitly be casted into unsigned char can be passed, even if its totally unrelated to the expected "enumeration" or if the value does not match the value of any of the expected consts
    

EDIT: Here I have found an interesting article about limitation in the type safety of enums: http://www.drdobbs.com/enumerations/184401797

like image 500
Kaiserludi Avatar asked Nov 08 '13 18:11

Kaiserludi


2 Answers

The big difference is the typing. The enum has a distinct type; the static const must have an existing integral type (although it can be used elsewhere). Which one is preferable depends on what you want: in the case of Direction, you probably want a unique type, and the enum is preferable. In other cases, what you really want is a named constant with an integral type, say as the dimension of an array. In those cases, static const is probably preferable.

like image 76
James Kanze Avatar answered Nov 07 '22 02:11

James Kanze


C++11 solves all of the contra enum points by means of strongly typed enums and improved scoping.

For a fixed set of values like your example of cardinal directions, I'd use enum.

like image 32
snips-n-snails Avatar answered Nov 07 '22 03:11

snips-n-snails