Search code examples
c++enumscoding-style

Should I use enums for things that are named after integers?


enum D6value {
    one = 1,
    two = 2,
    three = 3,
    four = 4,
    five = 5,
    six = 6 };

bool IsCriticalHit(D6value roll);

I like this because it makes for better documentation on the function parameter.

I dislike this because it's something that I just dreamed up and it makes me feel clever--which is usually how I feel immediately before regretting something.

Is this bad style?


Solution

  • If the caller's likely to have a value (whether hard-coded or run-time variable) of type D6Value to use when calling IsCriticalHit, then you effectively get compile-time enforcement of correctness of the function parameter: not that you can't hack around it and pass an out-of-range value, but you're unlikely to do it accidentally. That's potentially worthwhile.

    Countering that, it callers have ints they want to pass in, then they'll have the inconvenience of casting them to D6Value, which will work whether or not the int is in the 1 to 6 range. If IsCriticalHit forgoes defensive coding (checking roll is in range) due to a naive expectation that the enums always enforcing correctness, then your worse off than if you'd used ints and defensive coding practices. It's also verbose and an extra thing for other developers to get their head around.

    You should also think about the set of operations you'll want to perform on D6Value objects: with your enum, some operators won't be provided (e.g. +=(D6Value)) and operations like + produce results that may not be in the type-implied one..six range (and pre-C++11, may wrap if the implementation chooses a representation with too few bits; C++11 defaults to int as the underlying type).