Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Preventing casting ints to enums in C++

Tags:

c++

enums

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++?

like image 531
jazzandrock Avatar asked Feb 25 '18 01:02

jazzandrock


1 Answers

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) {}
};
like image 74
eerorika Avatar answered Oct 18 '22 16:10

eerorika