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:
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:
type safety is rather limited:
enum A { Entry1 = 1 }; enum B { Entry2 = 10 }; A a; if(a == Entry2) ; // ouch!
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
the namespacing for enums is suboptimal
if one doesn't wrap an enum into a separate namespace, then all its members will pollute the surrounding namespace.
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:
- better type support in C++ prior to C++ 11 - one can for example use types like unsigned char for the constants
- 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:
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