Base enum class inheritance

Viewed 94336

Is there a pattern where I can inherit enum from another enum in C++??

Something like that:

enum eBase 
{
   one=1, two, three
};


enum eDerived: public eBase
{
   four=4, five, six
};
13 Answers
#include <iostream>
#include <ostream>

class Enum
{
public:
    enum
    {
        One = 1,
        Two,
        Last
    };
};

class EnumDeriv : public Enum
{
public:
    enum
    {
        Three = Enum::Last,
        Four,
        Five
    };
};

int main()
{
    std::cout << EnumDeriv::One << std::endl;
    std::cout << EnumDeriv::Four << std::endl;
    return 0;
}

Not possible. There is no inheritance with enums.

You can instead use classes with named const ints.

Example:

class Colors
{
public:
  static const int RED = 1;
  static const int GREEN = 2;
};

class RGB : public Colors
{
  static const int BLUE = 10;
};


class FourColors : public Colors
{
public:
  static const int ORANGE = 100;
  static const int PURPLE = 101;
};

Kind of hacky but this is what I came up with if dealing with scoped enums:

enum class OriginalType {
   FOO,  // 0
   BAR   // 1
   END   // 2
};

enum class ExtendOriginalType : std::underlying_type_t<OriginalType> {
   EXTENDED_FOO = static_cast<std::underlying_type_t<OriginalType>>
                                           (OriginalType::END), // 2
   EXTENDED_BAR  // 3
};

and then use like:

OriginalType myOriginalType = (OriginalType)ExtendOriginalType::EXTENDED_BAR;

This answer is a variant of Brian R. Bondy answer. Since has been requested in a comment I'm adding it as answer. I'm not pointing about if it really worths though.

#include <iostream>

class Colors
{
public:
    static Colors RED;
    static Colors GREEN;

    operator int(){ return value; }
    operator int() const{ return value; }

protected:
    Colors(int v) : value{v}{} 

private:
    int value;
};

Colors Colors::RED{1};
Colors Colors::GREEN{2};

class RGB : public Colors
{
public:
    static RGB BLUE;

private:
    RGB(int v) : Colors(v){}
};

RGB RGB::BLUE{10};

int main ()
{
  std::cout << Colors::RED << " " << RGB::RED << std::endl;
}

Live at Coliru

My Solution is similar to some above, except that I wanted to return in my functions like an enum (constructor that takes the STATUS_ENUM value), and compare like an enum (operators that compare the STATUS_ENUM value to the class). I also wanted a clean way of using the base class without having to cast and check things (operator override). Lastly I wanted to make sure that only the type I specify can construct the class (deleted template).

        struct StatusReturn
        {
            /**
             * Use this to communicate trigger conditions internally to the caller.
             * - Extend this class with a child who adds more static const STATUS_ENUM values as options.
             * - When checking the return simply compare with != or == and the class will handle the rest.
             *   - This is true for a base class and a derived value, since this base class holds the value.
             */

            typedef int STATUS_ENUM;

            StatusReturn() = delete;
            
            template <typename T>
            StatusReturn(T) = delete;
            StatusReturn(STATUS_ENUM value): _value(value) {};

            // Operator overloads to compare the int to the class
            friend bool operator==(const StatusReturn & lhs, const STATUS_ENUM & rhs)
            { return lhs.getValue() == rhs; };
            friend bool operator!=(const StatusReturn & lhs, const STATUS_ENUM & rhs)
            { return !(lhs == rhs); };
            friend bool operator==(const STATUS_ENUM & lhs, const StatusReturn & rhs)
            { return lhs == rhs.getValue(); };
            friend bool operator!=(const STATUS_ENUM & lhs, const StatusReturn & rhs)
            { return !(lhs == rhs); };

            // Non-exit triggering return
            static const STATUS_ENUM CONTINUE = -1;

            // Exit triggering values
            static const STATUS_ENUM FAILED = 0;
            static const STATUS_ENUM SUCCESS = 1;
            static const STATUS_ENUM HALTED = 2;

            STATUS_ENUM getValue() const
            { return _value; };

        protected:
            STATUS_ENUM _value = CONTINUE;
        };

Some examples of use:

        StatusReturn shouldExit()
        {
            return successBool ? StatusReturn::SUCCESS : StatusReturn::CONTINUE;
        }

Which when called looks like:

        auto exitValue = shouldExit();
        if (exitValue != StatusReturn::CONTINUE)
        {
            return exitValue;
        }

Then a check of a derived class is as such:

        auto exitValue = shouldExit();
        if (exitValue != DerivedReturn::DO_STUFF)
        {
            return exitValue;
        }

Here, since DO_STUFF is also a STATUS_ENUM type, the operators just work without any explicit casting.

Impossible.
But you can define the enum anonymously in a class, then add additional enum constants in derived classes.

enum xx {
   ONE = 1,
   TWO,
   xx_Done
};

enum yy {
   THREE = xx_Done,
   FOUR,
};

typedef int myenum;

static map<myenum,string>& mymap() {
   static map<myenum,string> statmap;
   statmap[ONE] = "One";
   statmap[TWO] = "Two";
   statmap[THREE] = "Three";
   statmap[FOUR] = "Four";
   return statmap;
}

Usage:

std::string s1 = mymap()[ONE];
std::string s4 = mymap()[FOUR];
Related