Replace enums with classes in C++
Problem
The C++ enum types have some shortcomings like:- Can't convert to a string.
- Can't convert from a string.
- Can't extend with member functions.
// Color.cpp
class Color {
public:
static const Color Red;
static const Color Green;
static const Color Blue;
constexpr int value() const noexcept
{
return value_;
}
constexpr const char *name() const noexcept
{
return name_;
}
constexpr bool operator == (const Color &other) const noexcept
{
return value_ == other.value_;
}
constexpr bool operator < (const Color &other) const noexcept
{
return value_ < other.value_;
}
private:
template <std::size_t SIZE>
constexpr Color(int value, const char (&name)[SIZE]) noexcept
: value_(value), name_(name)
{
}
int value_;
const char *name_;
};
const Color Color::Red( 0, "Red");
const Color Color::Green(1, "Green");
const Color Color::Blue( 2, "Blue");
Some things to note:
- The constructor is private so it's not possible to accidently create additional
Color
instances other then the static ones listed in the class declaration. - The only way you can create now a
Color
instance is if you make a copy of one of the static instances. - It's not actually necessary to make the static
Color
instances const, because the members (value_
,name_
) are already const and so the compiler 'deletes' the default copy constructor and the default assignment operator. - The constructor parameters ensure that
name
must be initialized with a string literal. - The comparison operators are not free functions because we don't have a
converting constructor
which together with free comparison functions would allow us to for example compare
an integer with a
Color
.
// ColorUsage.cpp
int main(int, char *[])
{
Color color = Color::Blue;
color = Color::Green;
if (color == Color::Blue) {
cout << color.name() << endl;
}
return 0;
}
Notes
The cppreference.com website lists a couple of enum libraries.Written and © by P. Most ()