Suppose we have
enum class Month {jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec};
Each value is an int, 0 to 11. Then I expect variable of type Month to hold only these enumerated values. So here's the only OK way to create a variable:
Month m = Month::may;
But here are some other ways that language allows:
Month m1 = Month(12345);
Month m2 = static_cast<Month>(12345);
which is somewhat disappointing. How do I allow only the first way? Or how do people cope with poor enums in C++?
How do I allow only the first way?
Not possible with enums.
If you want an idiot proof "enum" that cannot be explicitly converted from (possibly invalid) values, then you can use a full blown class instead of an enum. Unfortunately that involves some boilerplate:
struct Month {
constexpr int value() noexcept { return v; }
static constexpr Month jan() noexcept { return 0; };
static constexpr Month feb() noexcept { return 1; };
static constexpr Month mar() noexcept { return 2; };
static constexpr Month apr() noexcept { return 3; };
static constexpr Month may() noexcept { return 4; };
static constexpr Month jun() noexcept { return 5; };
static constexpr Month jul() noexcept { return 6; };
static constexpr Month aug() noexcept { return 7; };
static constexpr Month sep() noexcept { return 8; };
static constexpr Month oct() noexcept { return 9; };
static constexpr Month nov() noexcept { return 10; };
static constexpr Month dec() noexcept { return 11; };
private:
int v;
constexpr Month(int v) noexcept: v(v) {}
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With