Search code examples
c++enumsscoped-enums

How to map different C++ classes to enum class values


I produce messages and each is receive by one object, chosen by an enum class member:

enum class ReceiverID
{
    R1,
    R2,
    MAX_NUM_RECEIVERS
};

struct Msg
{
    ReceiverID _receiverID;
    Data _data;
};

The receiving classes are stored in an array. The enum member indexes the array to access the receiving object:

void receive(const Msg& msg)
{
    const size_t arrIndex = static_cast<size_t>(msg._receiverID);
    
    if(nullptr == _array[arrIndex])
    {
        _array[arrIndex] = ???  // How do I associate the enum to the class?
    }
    
     _array[arrIndex].processMsg(msg);
}

It is possible the receiving object is missing. If this happens I'd like to use the enum to instantiate the missing object. However, this would require mapping the enum values to the receiving object type.

How can I map a class to each enum? (for all enums).

I'd like to generate a compiler error if a new enum is added but without a corresponding receiver class.

UPDATE

The receiving objects are polymorphic and so have a base class. The array is:

std::array<Base*, MAX_NUM_RECEIVERS> _array;

(removed unique_ptr to simplify question)


Solution

  • For on-the-fly creation of objects we could go for some kind of a factory method, e.g.:

    //In the Base class:
    static Base* createReceiver(ReceiverID recvID) //static member function
    {
        switch (recvID)
        {
            case ReceiverID::R1: return new R1Receiver();
            case ReceiverID::R2: return new R2Receiver();
            //...
            default: throw std::logic_error("Invalid ReceiverID");
        }
    }
    
    //...
    void receive(const Msg& msg) except(true)
    {
        const size_t arrIndex = static_cast<size_t>(msg._receiverID);
        if(nullptr == _array[arrIndex])
        {
            _array[arrIndex] = Base::createReceiver(msg._receiverID);
        }    
        _array[arrIndex]->processMsg(msg);
    }