Perhaps due to my background in other languages where the typing of enum
is more strict (*), I tend to think that if you want a type able to contain a set of constants, use an enum
, if you want a bunch of constants, use a bunch of constants and don't introduce a type where there is no need of one.
There have been considerations which made the choice of an enum
better at the time, but the only one I can think which survived the normalization of C++ 98 is compatibility with C and previous implementations of C++ (and some have kept as their style what was a necessity when they established it).
What has survived are the considerations which made the use of an additional type worrisome. The fact that the constants are of another type which is normally not used can interfere with overload resolution and type deduction in templates. Rules are such that it does usually what you want -- perhaps at the cost of an additional instantiation for the spurious enum
type -- but there are time when it isn't. For instance
template <typename T> MyClass<T> make_MyClass(T) {...}
return a MyClass<Size>
for make_MyClass(PAGE_SIZE)
where you probably expect a MyClass<int>
if the reason for introducing the enum wasn't to have a type but introduce some constants.
(*) note that such stricter typing of enum
was deemed sufficiently desirable that a variation is now provided as enum class
since C++11.