Can a C++ enum class have methods?
While the answer that "you can't" is technically correct, I believe you may be able to achieve the behavior you're looking for using the following idea:
I imagine that you want to write something like:
Fruit f = Fruit::Strawberry;
f.IsYellow();
And you were hoping that the code looks something like this:
enum class Fruit : uint8_t
{
Apple,
Pear,
Banana,
Strawberry,
bool IsYellow() { return this == Banana; }
};
But of course, it doesn't work, because enums can't have methods (and 'this' doesn't mean anything in the above context)
However, if you use the idea of a normal class containing a non-class enum and a single member variable that contains a value of that type, you can get extremely close to the syntax/behavior/type safety that you want. i.e.:
class Fruit
{
public:
enum Value : uint8_t
{
Apple,
Pear,
Banana,
Strawberry
};
Fruit() = default;
constexpr Fruit(Value aFruit) : value(aFruit) { }
#if Enable switch(fruit) use case:
// Allow switch and comparisons.
constexpr operator Value() const { return value; }
// Prevent usage: if(fruit)
explicit operator bool() const = delete;
#else
constexpr bool operator==(Fruit a) const { return value == a.value; }
constexpr bool operator!=(Fruit a) const { return value != a.value; }
#endif
constexpr bool IsYellow() const { return value == Banana; }
private:
Value value;
};
Now you can write:
Fruit f = Fruit::Strawberry;
f.IsYellow();
And the compiler will prevent things like:
Fruit f = 1; // Compile time error.
You could easily add methods such that:
Fruit f("Apple");
and
f.ToString();
can be supported.
No, they can't.
I can understand that the enum class
part for strongly typed enums in C++11 might seem to imply that your enum
has class
traits too, but it's not the case. My educated guess is that the choice of the keywords was inspired by the pattern we used before C++11 to get scoped enums:
class Foo {
public:
enum {BAR, BAZ};
};
However, that's just syntax. Again, enum class
is not a class
.