c++templatesmultiple-dispatch

Using parameter packs to automate dynamic_cast checks


I'm trying to implement a communication system inside of a GUI. I would like to avoid the visitor pattern for maintainability reasons. Likewise making a dynamic_cast if else statement is not maintainable. The closest I've come is implementing multiple dispatch with tables from Scott Meyers' More Effective C++.

So far I have:

SubmitCommand(BaseCommand* pCommand)
{
    m_Distpatcher->Dispatch<DerivedCommand1>(pCommand);
    m_Distpatcher->Dispatch<DerivedCommand2>(pCommand);
    m_Distpatcher->Dispatch<DerivedCommand3>(pCommand);
}

Where I would like to be is:

SubmitCommand(BaseCommand* pCommand)
{
    m_Distpatcher->Dispatch<DerivedCommand1,
                            DerivedCommand2,
                            DerivedCommand3>(pCommand);
}

Where dispatch is a automated way of checking dynamic_cast results for incoming commands.

    template<typename K>
    void Dispatch(ICommand* pCommand)
    {
        auto pConcreteCommand = dynamic_cast<K*>(pCommand);
        if (pConcreteCommand)
        {
            //call Recieve on the interface of the owner class
            m_pInstance->Recieve(pConcreteCommand);
        }
    }

In this case the specific module would be checked at compile time to make sure it has a function for each argument in the template. Is code block 2 possible?


Solution

  • You might do something like:

    template <typename ... Ts>
    void Distpatcher::Dispatch(BaseCommand* pCommand)
    {
        (DispatchUnique<Ts>(pCommand), ...); // C++17
    }
    

    so

    m_Distpatcher->Dispatch<DerivedCommand1,
                            DerivedCommand2,
                            DerivedCommand3>(pCommand);
    

    would be equivalent to

    m_Distpatcher->DispatchUnique<DerivedCommand1>(pCommand);
    m_Distpatcher->DispatchUnique<DerivedCommand2>(pCommand);
    m_Distpatcher->DispatchUnique<DerivedCommand3>(pCommand);